构造中的单个值与构造的参数列表

时间:2013-10-24 19:01:17

标签: c++ c++11

这个问题与下面转载的code snippet有关:

struct A { 
    A():b(0) { } 
    A(const A&, int b = 0):b(b) { } 
    int b; 
};

int main() {
  A a;

  const A& a1 = { a };  
  const A& a2 = { a, 1 };
  a.b = 2;   
  std::cout << a1.b << a2.b << std::endl;
}

a1赋值的右侧可以是构造中的单个值,也可以是构造的参数列表。标准中是否有任何指定哪种解释优先?对于a2,它是一个临时A的结构,如果我没有误解,它的地址被分配给a2。

BTW,在Coliru中用clang ++编译这段代码产生了输出21. gcc ++ - 4.8输出01.

2 个答案:

答案 0 :(得分:5)

自由于缺陷报告发布C ++ 11标准以来,列表初始化的定义发生了很大变化。

来自草案n3485(标准版发布后,有一些更正但没有C ++ 1y功能)[dcl.init.list] / 3

  

类型T的对象或引用的列表初始化定义如下:

     
      
  • 如果T是汇总[...]
  •   
  • 否则,如果初始化列表没有元素[...]
  •   
  • 否则,如果Tstd::initializer_list<E> [...]
  • 的特化   
  • 否则,如果T是班级类型[...]
  •   
  • 否则,如果初始化列表包含E类型的单个元素且T不是引用类型或其引用类型与E引用相关,则对象或引用从该元素初始化;如果将元素转换为T需要缩小转换,则程序格式不正确。
  •   
  • 否则,如果T是引用类型,则T引用的类型的prvalue临时值被列表初始化,并且引用绑定到该临时
  •   
  • [...]
  •   

在委员会的github回购(ce016c64dc)的最新草案中,这里只有一点点变化[dcl.init.list] / 3:

  
      
  • 否则,如果T是引用类型,T引用的类型的prvalue临时是copy-list-initialized或direct-list-initialized,具体取决于初始化的类型。引用,引用绑定到临时引用。
  •   

来自草案n3242(标准之前)[dcl.init.list] / 3:

  

类型T的对象或引用的列表初始化定义如下:

     
      
  • 如果初始化列表没有元素[...]
  •   
  • 否则,如果T是汇总[...]
  •   
  • 否则,如果Tstd::initializer_list<E> [...]
  • 的特化   
  • 否则,如果T是班级类型[...]
  •   
  • 否则,如果T是对类类型的引用,或者T是任何引用类型且初始化列表没有元素,则T引用的类型的prvalue临时值为list-initialized,引用绑定到那个临时的。
  •   
  • [...]
  •   

(我现在没有标准本身的副本。)


假设您的编译器实现了对缺陷报告的建议解决方案。然后,第一个例子

const A& a1 = { a };

初始化为const A& a1 = a;(无临时);和第二个例子

const A& a2 = { a, 1 };

初始化为const A& a2 = A(a,1);

答案 1 :(得分:1)

  

8.5.4 / 3 对象或类型T的引用的列表初始化定义如下:
  ...

     
      
  • 否则,如果T是引用类型,则由T引用的类型的prvalue临时列表进行列表初始化,并且引用绑定到   那是暂时的。
  •   

在您的示例中,a1不直接绑定到a,而是绑定到a构建的临时副本。