我有一个接受initializer_list作为参数的构造函数:
A::A(std::initializer_list<uint32_t> arg)
: vec(arg)
{
}
问题是它允许为arg设置initializer_list零或空值:
A {}
如何强制使用非零的initializer_list?
答案 0 :(得分:5)
当初始化器为{}
时,默认构造函数优先于std::initializer_list
构造函数,但是当不存在前者时将使用后者。因此,为了强制执行编译错误,您需要显式删除默认构造函数,以便仍选择默认构造函数但不能使用它:
struct A {
A() = delete;
A(std::initializer_list<uint32_t>) { /* ... */ }
};
但是,在编译时,您不能阻止用户手动构造一个空的std::initializer_list
对象并将其传递给您。在这种情况下,您需要引发异常以指示构造失败。
答案 1 :(得分:1)
您无法使用初始化程序列表完成此操作 -您必须进行运行时(而非编译时)验证。
但是,只是为了好玩:如果您愿意放弃初始化程序列表,并接受数组作为构造函数的输入,则可以得到想要的东西。
class A {
private:
std::vector<int> v_;
public:
template<typename T, std::size_t N>
A(const T(&v)[N]) : v_(std::begin(v), std::end(v)) {
static_assert(N > 0, "Requires nonempty array.");
}
};
int main() {
int empty_arr[] = {};
int arr[] = {1};
// The following no longer works as there is no constructor that takes in as
// input an initializer list.
// A a{1};
// A b{};
A c({2});
// So does this:
A d(arr);
// And this would be a compilation error, even if there was no static_assert.
// C++ standard says you can't have an array of size zero. The static_assert in
// the class is just to make it easier for others to see what your intention is.
// A e(empty_arr);
}