Why doesn't C++11 curly brace initialzation in constructor initialization list work when parens initializaton does?

那年仲夏 提交于 2019-12-03 11:05:20

Short answer: This was a bug in the Standard which is fixed in C++14, and g++ 4.9 has the fix (retroactively applied to C++11 mode too). Defect Report 1288


Here's a simpler example:

struct S
{
    int x;
    S() { }     // this causes S to not be an aggregate (otherwise aggregate 
                // initialization is used instead of list initialization)
};

S x = 5;
S const &y { x } ;    

x = 6;
std::cout << y << std::endl;     // output : 5

In the text of C++11, the meaning of S const &y {x}; is not to bind y to x; in fact the meaning is to create a temporary and bind a reference to that. From C++11 [dcl.init.ref]/3:

Otherwise, if T is a reference type, a prvalue temporary of the type referenced by T is list-initialized, and the reference is bound to that temporary. [Note: As usual, the binding will fail and the program is ill-formed if the reference type is an lvalue reference to a non-const type. —end note ]

This is pretty silly , clearly the intent of this code is to bind y directly to x. In C++14 the text was changed:

Otherwise, if the initializer list has a single element of type E and either T is not a reference type or its referenced type is reference-related to E, the object or reference is initialized from that element;

Since a type is reference-related to itself (or one of its base classes), in my sample here and in your actual code, it should actually bind correctly.


Your error message comes from the compiler following the C++11 wording and attempting to create a temporary from base to bind the reference to; and this fails because base is of an abstract type.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!