使用构造函数参数初始化成员数组(使用普通旧数组)
Initialize member array with constructor argument (with plain old arrays)
与此非常相似:
但我不使用 std::array
,或者更确切地说,如果有其他选择,我宁愿不使用它。
我有这个class(简体):
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>&&’
e
不是因为 StaticArray
不是“聚合类型”。
我不太了解 C++ 的复杂性,不知道这里发生了什么。我明白给定 int a[4]; int b[4];
你不能简单地做 a = b;
。但是用 items{1, 2, 3, 4}
替换构造函数中的 items{newItems}
效果很好, items{{1, 2, 3, 4}}
!
我怀疑是整个参数类型衰减问题搞砸了。
我可以完全删除所有构造函数并让 e
工作,但是这样就允许使用大小不合适的列表进行初始化,这很愚蠢。
任何解决方法的指示?我真的不想用模板魔术或 std::array
之类的 kajiggery。越“纯”越好
这个构造函数:
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 的空初始化列表有点奇怪,但还算不错。
与此非常相似:
但我不使用 std::array
,或者更确切地说,如果有其他选择,我宁愿不使用它。
我有这个class(简体):
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>&&’
e
不是因为 StaticArray
不是“聚合类型”。
我不太了解 C++ 的复杂性,不知道这里发生了什么。我明白给定 int a[4]; int b[4];
你不能简单地做 a = b;
。但是用 items{1, 2, 3, 4}
替换构造函数中的 items{newItems}
效果很好, items{{1, 2, 3, 4}}
!
我怀疑是整个参数类型衰减问题搞砸了。
我可以完全删除所有构造函数并让 e
工作,但是这样就允许使用大小不合适的列表进行初始化,这很愚蠢。
任何解决方法的指示?我真的不想用模板魔术或 std::array
之类的 kajiggery。越“纯”越好
这个构造函数:
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 的空初始化列表有点奇怪,但还算不错。