带有initializer_list的可选构造函数

bal*_*lki 13 c++ optional c++14 c++17

这个特殊构造函数采用初始化列表的目的是什么.有人可以举例说明什么时候有用吗?

template <class U, class... Args>
constexpr explicit optional(in_place_t, initializer_list<U> il, Args&&... args);
Run Code Online (Sandbox Code Playgroud)

以上与此有何不同?

template <class... Args> 
constexpr explicit optional(in_place_t, Args&&... args); 
Run Code Online (Sandbox Code Playgroud)

参考:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3793.html#optional.object.ctor

PS不确定是使用c ++ 14还是c ++ 1z标签.我认为应该有c ++技术规范的标签

Pra*_*ian 10

两个独立构造函数的原因是允许构造带有initializer_list构造函数参数的对象(可选地后跟任意参数列表).假设您的类型foo如下所示:

struct foo
{
    foo(std::initializer_list<int>) {}
};
Run Code Online (Sandbox Code Playgroud)

在没有构造函数的情况下

template <class U, class... Args>
constexpr explicit optional(in_place_t, initializer_list<U> il, Args&&... args);
Run Code Online (Sandbox Code Playgroud)

你将无法构建一个optionalas

optional<foo> o(in_place, {1, 2, 3});
Run Code Online (Sandbox Code Playgroud)

上述操作失败,因为braced-init-list没有类型,因此模板参数推断失败.你不得不求助于这样的事情:

auto il = {1, 2, 3};
optional<foo> o(in_place, il);
Run Code Online (Sandbox Code Playgroud)

拥有接受initializer_list参数的构造函数在构造optional对象时允许更自然的语法.

这是一个演示两个构造函数的实用程序的最小示例.

  • @balki绝对,这就是为什么你不能做`std :: vector <foo>().emplace_back({1,2,3})`但是`std :: vector <foo>().emplace_back( std :: initializer_list <int> {1,2,3})`成功. (6认同)
  • 嗯.是不是同样的解释适用于`vector.emplace_back`? (3认同)
  • @balki我无法确定,但是可能是一个疏忽。emplace函数和列表初始化都是C ++ 11的新功能,可能没有人想到这种特殊情况。还请记住,容器必须委托给分配器以构造新元素。也许关于分配器的事情使这一点难以实现。或者它可能只是在等待新提案的提交,因为看起来与上面的签名相似的`emplace(_back)`重载的添加将是向后兼容的更改。 (2认同)