使用构造函数参数初始化成员数组(使用纯旧数组)



与此非常相似:C++用构造函数参数初始化成员数组
但我不使用std::array,或者更确切地说,如果有其他选项,我真的不想使用它。

我有这个类(简化(:

template<typename T, int length> // Line 53
class StaticArray
{
public:
T items[length];
StaticArray() = default;
StaticArray(T newItems[length]) : items{newItems} { }
};
int main()
{
StaticArray<int, 4> a;                                       // Works (uninitialized)
StaticArray<int, 4> b = StaticArray<int, 4>();               // Works (initialized to 0)
//StaticArray<int, 4> c = StaticArray<int, 4>({});           // Does not compile
//StaticArray<int, 4> d = StaticArray<int, 4>({1, 2, 3, 4}); // Does not compile
//StaticArray<int, 4> e = {1};                               // Does not compile
return 0;
}

具有ab的线路工作良好。但c不编译:

....main.cpp:59: error: invalid conversion from ‘int*’ to ‘int’ [-fpermissive]
....main.cpp:66:51:   required from here
....main.cpp:59:49: error: invalid conversion from ‘int*’ to ‘int’ [-fpermissive]
59 |         StaticArray(T newItems[length]) : items{newItems} { }
|                                                 ^~~~~~~~
|                                                 |
|                                                 int*

d:也没有

no matching function for call to ‘StaticArray<int, 4>::StaticArray(<brace-enclosed initializer list>)’
....main.cpp: In function ‘int main()’:
no matching function for call to ‘StaticArray<int, 4>::StaticArray(<brace-enclosed initializer list>)’
67 |     StaticArray<int, 4> d = StaticArray<int, 4>({1, 2, 3, 4});
|                                                             ^
....main.cpp:59:9: note: candidate: ‘StaticArray<T, length>::StaticArray(T*) [with T = int; int length = 4]’
59 |         StaticArray(T newItems[length]) : items{newItems} { }
|         ^~~~~~~~~~~
....main.cpp:59:23: note:   no known conversion for argument 1 from ‘<brace-enclosed initializer list>’ to ‘int*’
59 |         StaticArray(T newItems[length]) : items{newItems} { }
|                     ~~^~~~~~~~~~~~~~~~
....main.cpp:58:9: note: candidate: ‘StaticArray<T, length>::StaticArray() [with T = int; int length = 4]’
58 |         StaticArray() = default;
|         ^~~~~~~~~~~
....main.cpp:58:9: note:   candidate expects 0 arguments, 1 provided
....main.cpp:54:7: note: candidate: ‘constexpr StaticArray<int, 4>::StaticArray(const StaticArray<int, 4>&)’
54 | class StaticArray
|       ^~~~~~~~~~~
....main.cpp:54:7: note:   no known conversion for argument 1 from ‘<brace-enclosed initializer list>’ to ‘const StaticArray<int, 4>&’
....main.cpp:54:7: note: candidate: ‘constexpr StaticArray<int, 4>::StaticArray(StaticArray<int, 4>&&)’
....main.cpp:54:7: note:   no known conversion for argument 1 from ‘<brace-enclosed initializer list>’ to ‘StaticArray<int, 4>&&’

CCD_ 6不是因为CCD_;聚合类型";。

我不太了解C++的复杂性,不知道这里发生了什么。我确实理解,给定int a[4]; int b[4];,你不能简单地做a = b;。但是用items{1, 2, 3, 4}替换构造函数中的items{newItems}效果很好,items{{1, 2, 3, 4}}也是如此
我怀疑整个论证类型的衰变是把这件事搞砸了
我可以完全删除所有构造函数,并让e工作,但这允许使用大小不合适的列表进行初始化,这很愚蠢。

有什么解决办法吗?我真的不想为模板魔术或类似std::array的kajigery而烦恼。";更纯净";越好。

此构造函数:

template<typename... TNewItems>
StaticArray(TNewItems... newItems)
: items{newItems...}
{
static_assert(sizeof...(newItems) == length, "Number of supplied items must match the length of the array.");
}

像这样使用:

StaticArray<int, 4> a;                                     // Works (uninitialized for int, calls the default constructor for complex types)
StaticArray<int, 4> b = StaticArray<int, 4>();             // Works (0, 0, 0, 0)
StaticArray<int, 4> c = StaticArray<int, 4>({});           // Weirdly works (0, 0, 0, 0; does not call the custom constructor)
StaticArray<int, 4> d = StaticArray<int, 4>({1, 2, 3, 4}); // Works (1, 2, 3, 4)
StaticArray<int, 4> e =                     {1, 2, 3, 4};  // Works (1, 2, 3, 4)
//StaticArray<int, 4> f = StaticArray<int, 4>({1, 2});       // Fails to compile
//StaticArray<int, 4> g =                     {1, 2};        // Fails to compile

模板的魔力相当小。初始化器列表中的wong类型(只要C++通常捕捉到错误的类型(的错误消息非常清晰,即使对于模板化的类也是如此
static_assert允许检查项目数量是否不正确。不匹配时的错误信息非常清晰
导致所有内容都初始化为0的空初始值设定项列表有点奇怪,但也不算太糟。

最新更新