与此非常相似: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;
}
具有a
和b
的线路工作良好。但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的空初始值设定项列表有点奇怪,但也不算太糟。