简体   繁体   English

如何确保initializer_list不为零

[英]How to ensure that initializer_list is not zero

I have a constructor that accepts a initializer_list as argument: 我有一个接受initializer_list作为参数的构造函数:

A::A(std::initializer_list<uint32_t> arg)
    : vec(arg)
{
}

The issue is that it allows initializer_list zero or empty values for arg: 问题在于,它允许initializer_list的arg值为零或为空:

A {}

How can I force a non-zero initializer_list ? 我怎样才能强制一个非零的initializer_list?

When the initializer is {} , a default constructor takes precedence over a std::initializer_list constructor, but the latter will be used when the former is not present. 当初始化为{} ,默认构造函数优先于std::initializer_list构造函数,但是当不存在前者时将使用后者。 Therefore, in order to force a compile error, you need to explicitly delete the default constructor, so that the default constructor is still selected but cannot be used: 因此,为了强制执行编译错误,您需要显式删除默认构造函数,以便仍选择默认构造函数但不能使用该默认构造函数:

struct A {
    A() = delete;
    A(std::initializer_list<uint32_t>) { /* ... */ }
};

However, at compile time, you can't stop the user from manually constructing an empty std::initializer_list object and passing it in. You would need to throw an exception to signal construction failure in that case. 但是,在编译时,您不能阻止用户手动构造一个空的std::initializer_list对象并将其传递给您。在这种情况下,您需要引发异常以指示构造失败。

You can't do this with initializer lists -- you'd have to do run-time (not compile-time) validation. 您不能使用初始值设定项列表来执行此操作-您必须执行运行时(而非编译时)验证。

But, just for fun: if you are willing to forego initializer lists, and accept an array as an input into your constructor, you can get what you want. 但是,只是为了好玩:如果您愿意放弃初始化器列表,并接受数组作为构造函数的输入,则可以得到想要的东西。

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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM