gpt4 book ai didi

c++ - 如何通过CTOR从constexpr中的STRING LITERAL初始化char数组成员

转载 作者:行者123 更新时间:2023-12-02 10:09:56 25 4
gpt4 key购买 nike

所以这工作:

        template<size_t N>
struct LTxt
{
char txt[N];
};
void Test1()
{
//LTxt<10> fromliteral = "test1"; does not work, but ok
LTxt<10> fromlitera2 = { "test2" };
constexpr LTxt<10> fromliteral3 = { "test3" };
}
但是,当您为该结构编写构造函数时,就会失去该自动“特权”。
我可以写什么构造函数实现来保留该功能。
我尝试了很多事情:(注释的代码不起作用)
template<size_t N>
struct LTxt2
{
char txt[N];

//LTxt2() = default; // doesnt change anything

template<size_t N>
constexpr LTxt2(const char(&sz)[N])
//: txt{ sz } // Error C2075 array initialization requires a brace - enclosed initializer list
{
for (int c = 0; c < N; ++c) txt[c] = sz[c];
}
};
void Test2()
{
LTxt2<10> fromliteral = "test1";
//constexpr LTxt2<10> fromliteral2 = "test2";
LTxt2<10> fromliteral3 = { "test3" };
//constexpr LTxt2<10> fromliteral4 = { "test4" };
LTxt2<10> fromliteral5("test5");
//constexpr LTxt2<10> fromliteral6("test6");
LTxt2<10> fromliteral7({ "test7" });
//constexpr LTxt2<10> fromliteral8({ "test8" });
}

template<size_t N>
struct LTxt3
{
char txt[N];

constexpr LTxt3(std::initializer_list<char> list)
//:txt(list) {}
//:txt{ list }// {}
{
int c = 0;
for (auto p = list.begin(); p != list.end(); ++p, ++c)
txt[c] = *p;
}
};
void Test3()
{
//LTxt3<10> fromliteral = "test1";
//constexpr LTxt3<10> fromliteral2 = "test2";
//LTxt3<10> fromliteral3 = { "test3" }; //why in the name of fuck that doesnt work
//constexpr LTxt3<10> fromliteral4 = { "test4" };
//LTxt3<10> fromliteral5("test5");
//constexpr LTxt3<10> fromliteral6("test6");
//LTxt3<10> fromliteral7({ "test7" });
//constexpr LTxt3<10> fromliteral8({ "test8" });
LTxt3<10> fromliteral9 = { 't','e','s','t','9' };
//constexpr LTxt3<10> fromliteral10 = { 't','e','s','t','1', '0' };
}

template<size_t N>
struct LTxt4
{
char txt[N];

template<typename ... Params>
constexpr LTxt4(Params ... sz)
: txt{ sz... }
{}
};


void Test4()
{
//LTxt4<10> fromliteral = "test1";
//LTxt4<10> fromliteral = { "test1" };
//LTxt4<10> fromliteral { "test1" };
//LTxt4<10> fromliteral("test1");
LTxt4<10> fromliteral = { 't','e','s','t','1' };
constexpr LTxt4<10> fromliteral2 = { 't','e','s','t','2' };
}

最佳答案

我想出了这个:

#include <iostream>
#include <stdexcept>

template<size_t N>
struct LTxt
{
char txt[N] {};
};


template <class Char, Char... Cs>
constexpr auto operator""_txt()
{
LTxt<sizeof...(Cs)> text;

size_t index = 0;
auto addChar = [&](char c)
{
text.txt[index] = c;
index++;
};

((addChar(Cs)), ...);

return text;
}

int main() {
constexpr auto txt = "test"_txt;

for (int i = 0 ; i < 4 ; i++)
{
std::cout << txt.txt[i] << std::endl;
}

}
注意:带有字符参数包的字符串文字运算符模板是GNU扩展,不适用于 -pedantic-errors。 clang和gcc都支持它。

我要支持以下语法:
std::cout << txt.txt << std::endl;
您需要添加一个 '\0':
template <class Char, Char... Cs>
constexpr auto operator""_txt()
{
LTxt<sizeof...(Cs)+1> text;
size_t index = 0;
auto addChar = [&](char c)
{
text.txt[index] = c;
index++;
};
((addChar(Cs)), ...);
text.txt[index] = '\0';
return text;
}

语法: ((addChar(Cs)), ...);fold expression
在c++ 17之前,可以使用此技巧模拟它:
auto initializerList = {
(
addChar(Cs) // real code
, 0 // the expression is evaluated at 0 each time
)... // expand the parameter pack,
, 0 // if we do: ""_txt;
// we need at least one element for the auto deduction
};
(void) initializerList; // silence warning
之所以有效,是因为 parameter pack扩展:

expands to comma-separated list of zero or more patterns. Pattern must include at least one parameter pack.


因此,它将为 addChar(Cs),0中的每个 char重复整个 Cs

关于c++ - 如何通过CTOR从constexpr中的STRING LITERAL初始化char数组成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64072879/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com