为什么= {}初始化不适用于元组?

时间:2015-08-19 00:36:12

标签: c++ c++11 tuples initializer-list list-initialization

对我而言pair只是tuple的特例,但令我惊讶的是:

pair<int, int> p1(1, 2);   // ok
tuple<int, int> t1(1, 2);  // ok

pair<int, int> p2={1, 2};  // ok
tuple<int, int> t2={1, 2}; // compile error

为什么我们使用{}初始化tuple时会有区别?

我甚至试过g++ -std=c++1y但仍有错误:

a.cc: In function 'int main()':
a.cc:9:29: error: converting to 'std::tuple<int, int>' from initializer list would use explicit constructor 'constexpr std::tuple<_T1, _T2>::tuple(_U1&&, _U2&&) [with _U1 = int; _U2 = int; <template-parameter-2-3> = void; _T1 = int; _T2 = int]'
     tuple<int, int> t2={1, 2};
                             ^

2 个答案:

答案 0 :(得分:25)

除了Praetorian's correct answer(我已经投票赞成)之外,我还想添加更多信息......

Post-C ++ 14,该标准已更改为允许:

tuple<int, int> t2={1, 2}; 

编译并具有预期的语义。执行此操作的提案是N4387。这也将允许构造如:

tuple<int, int>
foo()
{
    return {1, 2};
}

只有当T中的所有tuple都可以从所有参数中隐式地构建时,才允许它。

作为一个不合规的扩展,libc ++已经实现了这种行为。

答案 1 :(得分:24)

您尝试拨打的tuple constructorexplicit,因此copy-list-initialization will fail。相应的pair constructor不是explicit

将您的代码更改为

tuple<int, int> t2{1, 2};

它会编译。