gpt4 book ai didi

c++ - C++:在constexpr构造函数中初始化成员数组

转载 作者:行者123 更新时间:2023-12-02 09:53:27 24 4
gpt4 key购买 nike

我正在c++ 17中实现一个类,该类需要能够在编译时使用constexpr构造函数构造一个对象。该对象具有一个数组成员,我似乎无法通过参数对其进行初始化。

我一直在尝试使用std::initializer_list,类似于以下内容:

#include <cstdint>
#include <initializer_list>

struct A {
char data[100];

constexpr A(std::initializer_list<char> s): data(s) {}
};

int main() {
constexpr A a{"abc"};
}

但这由于某些原因不起作用。
clang 6.0(也在以后的版本中尝试过)告诉我我错了,尽管我正在按照它说的去做:

test_initializer_list.cpp:7:46: error: array initializer must be an initializer list or string literal
constexpr A(std::initializer_list<char> s): data(s) {}

(请注意,如果我直接给它一个字符串文字,如 data("abc"),它将编译)
g++(7.5.0)说我由于某种原因不能使用初始化列表-但是,如果这样,我可以使用什么?

test_initializer_list.cpp:7:52: error: incompatible types in assignment of 'std::initializer_list<char>' to 'char [100]'
constexpr A(std::initializer_list<char> s): data(s) {}
^

难道我做错了什么?

最佳答案

解释将很长,但请忍受。

您不能使用std::initializer_list初始化数组。

当您编写类似int arr[] = {1,2,3}的内容时,用大括号括起来的部分不是std::initializer_list

If you don't believe me, consider a similar initialization for a structure:

struct A {int x; const char *y;};
A a = {1, "2"};

Here, {1, "2"} can't possibly be an std::initializer_list, because the elements have different types.



C++语法将这些用大括号括起来的列表称为 braced-init-lists
std::initializer_list是一个不可思议的类(即在标准C++中不可实现),可以从braced-init-list构造它。

如您所见, std::initializer_list不能代替大括号初始列表。 “括号初始化列表”是指特定的语法构造,因此数组的初始化程序(例如,在成员初始化列表中)必须从字面上是括号括起来的列表。您不能将此列表保存到变量,以后再用它初始化数组。
constexpr A() : data{'1','2','3'} {} // Valid
constexpr A(initializer_list<char>/*or whatever*/ list) : data{list} {} // Not possible

一种可能的解决方案是使用循环将元素从 std::initializer_list复制到数组中。

由于构造函数是 constexpr,因此必须使用某种东西来初始化数组。使用 : data{}将其初始化为零:
constexpr A(std::initializer_list<char> s) : data{} {/*copy elements here*/}

现在 A a({'1','2','3'});可以使用了。但是 A a("123");仍然不会。

字符串文字( "123")既不是大括号初始列表也不是 std::initializer_list,并且不能转换为它们。

使用字符串文字( char)初始化 char x[] = "123";数组有一条特殊规则。除了支撑初始列表外,该语法还允许在其中使用字符串文字。

它必须是字符串文字,即用引号引起来的字符串;一个 const char *变量或另一个 char数组将不起作用。

如果要使 A a("123");有效,则构造函数的参数必须是 const char *(还有其他一些选项,但在这里没有太大帮助)。使用循环将字符从指向的内存复制到数组中。不要忘了用零初始化数组( : data{}),因为您的构造函数是 constexpr

还有第三种选择:用 char data[100]替换 std::array,并将构造函数的参数设为 std::array。与普通数组不同,可以复制这些数组,因此 : data(list)将起作用。可以使用大括号初始列表( std::array)和大括号括起来的字符串文字( A a({'1','2','3'});)初始化 A a({"123"});

还有另一种选择:删除构造函数。然后,您的 struct将成为聚合(简单地说,没有自定义构造函数的结构,可以使用braced-init-list进行成员初始化)。然后 A a{{'1','2','3'}};A a{'1','2','3'};(大括号可以省略)和 A a{"123"};都可以使用。

关于c++ - C++:在constexpr构造函数中初始化成员数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62319929/

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