ory*_*unn 12 c++ initialization reference c++11 list-initialization
初始化对抽象类型的引用时,构造函数初始化列表中的{}初始化如何与()初始化不同?以下课程栏:
class AbstractBase
{
public:
AbstractBase() {}
virtual ~AbstractBase() = default;
virtual void ab() = 0;
};
class Foo : public AbstractBase
{
public:
Foo() {}
void ab() {}
};
class Bar
{
public:
Bar(const AbstractBase& base) : myBase{base} {}
private:
const AbstractBase& myBase;
};
int main()
{
Foo f{};
Bar b{f};
}
Run Code Online (Sandbox Code Playgroud)
编译时,我收到错误
test5.cpp: In constructor ‘Bar::Bar(const AbstractBase&)’:
test5.cpp:22:48: error: cannot allocate an object of abstract type ‘AbstractBase’
Bar(const AbstractBase& base) : myBase{base}
^
test5.cpp:2:7: note: because the following virtual functions are pure within ‘AbstractBase’:
class AbstractBase
^
test5.cpp:8:18: note: virtual void AbstractBase::ab()
virtual void ab() = 0;
Run Code Online (Sandbox Code Playgroud)
换线
Bar(const AbstractBase& base) : myBase(base) {}
Run Code Online (Sandbox Code Playgroud)
它编译并运行良好.
通过阅读Stroustrup的C++ 11书籍,我认为在大多数情况下{}与()相同,除非在构造函数之间存在歧义,这些构造函数采用std :: initializer_list <>和其他构造函数,以及案例在哪里使用auto作为类型,我在这里都没有.
M.M*_*M.M 13
简短回答:这是标准中的一个错误,它在C++ 14中修复,而g ++ 4.9有修复(也追溯应用于C++ 11模式).缺陷报告1288
这是一个更简单的例子:
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
Run Code Online (Sandbox Code Playgroud)
在C++ 11的文字,的意思S const &y {x};
是不结合y
到x
; 实际上意思是创建一个临时的并绑定对它的引用.来自C++ 11 [dcl.init.ref]/3:
否则,如果T是引用类型,则由T 引用的类型的prvalue临时值被列表初始化,并且引用绑定到该临时值.[注意:像往常一样,如果引用类型是非const类型的左值引用,则绑定将失败并且程序格式错误. - 尾注]
这非常愚蠢,显然这段代码的意图是y
直接绑定到x
.在C++ 14中,文本被更改:
否则,如果初始化列表具有E类型的单个元素且T不是引用类型或其引用类型与E引用相关,则从该元素初始化对象或引用;
由于类型与其自身(或其基类之一)的引用相关,在我的示例和实际代码中,它实际上应该正确绑定.
您的错误消息来自编译器遵循C++ 11的措辞并尝试创建临时base
来绑定引用; 这是失败的,因为base
它是一个抽象类型.
归档时间: |
|
查看次数: |
1366 次 |
最近记录: |