【问题标题】:Why ={} initialization doesn't work for tuple?为什么 ={} 初始化不适用于元组?
【发布时间】:2015-11-12 02:46:48
【问题描述】:

对我来说,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};
                             ^

【问题讨论】:

  • 如果你想要复制初始化语法,你应该可以做auto t2=tuple&lt;int, int&gt;{1, 2};。重新错误,错误信息说明了一切。

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


【解决方案1】:

您尝试调用的tuple constructorexplicit,所以copy-list-initialization will fail。对应的pair constructor不是explicit

将您的代码更改为

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

它会编译。

【讨论】:

  • tuple 使用显式构造函数有什么原因吗?
  • @Deqing 如果没有,那么包含单个类型的 tuple 可以从可转换为该类型的值隐式构造。
  • @Praetorian 为了避免这种情况,也许元组可以让显式构造函数采用一个参数,而非显式构造函数采用两个或更多参数?
  • @MattMcNabb 查看霍华德的回答,看起来这个问题已经以不同的方式解决了
【解决方案2】:

除了Praetorian'scorrect answer(我已投赞成票)之外,我还想补充一点信息...

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

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

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

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

只有在tuple 中的所有T 都可以从所有参数中隐式构造时才允许这样做。

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

【讨论】:

  • 你说“不符合”:这个扩展是否会改变任何在 C++14 下正确的代码的行为?
  • @MattMcNabb:是的。 is_convertible&lt;int, std::tuple&lt;int&gt;&gt;{} 在 C++14 中为假,在 C++1z 中为真。 C++ 内省的力量已经变得如此强大,以至于现在几乎不可能编写符合标准的扩展。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-17
  • 1970-01-01
  • 1970-01-01
  • 2021-12-06
相关资源
最近更新 更多