29

对我来说 apair只是 a 的特例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};
                             ^
4

2 回答 2

30

除了Praetorian 的 正确答案(我赞成)之外,我想添加更多信息......

在 C++14 之后,标准已更改为允许:

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

编译并具有预期的语义。这样做的建议是N4387。这也将允许以下构造:

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

T只有在tuple所有参数都可以从所有参数中隐式构造时,它才允许它。

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

于 2015-08-19T00:53:31.843 回答
27

您尝试调用的tuple构造函数explicit是,因此复制列表初始化将失败。对应的pair构造函数不是explicit

将您的代码更改为

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

它会编译。

于 2015-08-19T00:41:23.343 回答