假设我有以下模板类:
template<int R> class dummy{
public:
// functions
private:
int arr[R];
};
是否可以创建一个构造函数,它接受恰好 R 个用于初始化
array
的参数?
像这样使用的东西:
dummy<3> a(1,2,3); // where array[0] is set to 1, array[1] is set to 2, and so on...
我知道如何达到相同的结果:
template<int R> class dummy{
public:
dummy(const int(&list)[R]){
for (int i = 0; i < R; i++) arr[i] = list[i];
}
private:
int arr[R];
};
然后使用它:
dummy<3> a({1,2,3}); // OK
dummy<3> b({1,2}); // also OK but arr[2] will be set to 0
dummy<3> c({1,2,3,4}); // compile-time error
问题是我想要编译时保证传递的列表恰好是 R 的大小,而不是更大,不是更小。如果列表较大,上述代码的编译器会抱怨,但如果较小,则不会。
我看到了这个answer,但其中的大小是由函数调用自动确定的,并且硬编码值 3 是断言的一部分。我无法使用 static_assert,因为 R 将始终是类初始化设置的值(例如,
dummy<3>
设置 R=3
,并且如果列表小于 3,构造函数调用将用 0 填充列表)。
如何保证编译时传递的参数个数正好是R?
如果将构造函数参数化,则
static_assert()
会很好地工作。工作示例:https://godbolt.org/z/dcP683cdh
#include <cstddef>
template <int R>
class dummy {
public:
template <size_t N>
explicit dummy(const int (&list)[N]) {
static_assert(N == R);
for (int i = 0; i < R; i++)
arr[i] = list[i];
}
private:
int arr[R];
};
dummy<3> a({1, 2, 3});
dummy<3> b({1, 2});
dummy<3> c({1, 2, 3, 4});
int main() {}