gpt4 book ai didi

c++ - 当 parent 初始化时,为什么构造函数初始化列表中的 C++11 花括号初始化不起作用?

转载 作者:IT老高 更新时间:2023-10-28 23:17:25 29 4
gpt4 key购买 nike

在初始化对抽象类型的引用时,构造函数初始化列表中的 {} 初始化与 () 初始化有何不同?拿下面的类吧:

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};

}

编译的时候报错

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;

换行

Bar(const AbstractBase& base) : myBase(base) {}

它编译并运行良好。

阅读 Stroustrup 的 C++11 书,我的印象是 {} 在大多数情况下都与 () 相同,除非在采用 std::initializer_list<> 的构造函数和其他构造函数之间存在歧义,以及使用 auto 作为类型的情况,我在这里都没有这样做。

最佳答案

简短回答:这是标准中的一个错误,已在 C++14 中修复,g++ 4.9 已修复(也可追溯应用于 C++11 模式)。 Defect Report 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

在C++11的文本中,S const &y {x};的意思是不把y绑定(bind)到x ;实际上意思是创建一个临时的并绑定(bind)一个引用。来自 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 ]

这很傻,很明显这段代码的目的是将y直接绑定(bind)到x。在 C++14 中,文本已更改:

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;

由于类型与自身(或其基类之一)相关,因此在我的示例和您的实际代码中,它实际上应该正确绑定(bind)。


您的错误消息来自编译器,遵循 C++11 的措辞,并试图从 base 创建一个临时文件以将引用绑定(bind)到;这失败了,因为 base 是抽象类型。

关于c++ - 当 parent 初始化时,为什么构造函数初始化列表中的 C++11 花括号初始化不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26640866/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com