c++ - gcc中的初始化列表错误?

标签 c++ c++11 gcc initializer-list

考虑如下代码,其中BD通过B1B2继承的虚拟基类:

#include <iostream>

class B
{
protected:
    int x;

protected:

    B(int x) : x{x}{std::cout << x << std::endl;}
};

class B1 : virtual public B
{
protected:

    B1() : B(0){}
};

class B2 : virtual public B
{
protected:

    B2() : B(10){}
};

class D : public B1, public B2
{
public:

    D() : B(99), B1(), B2() {}
    void print() {std::cout << "Final: " << x << std::endl;}
};

int main() {
    D d;
    d.print();
    return 0;
}

查看工作示例 here .我在 B 的构造函数中使用输出,并在 D 完全构造之后跟踪正在发生的事情。当我使用 g++-4.8.1 编译上述示例时,一切正常。它打印

99
Final: 99

因为 B 的构造函数从最派生类 (D) 调用一次,这也决定了 x 的最终值。

现在是奇怪的部分:如果我换行

D() : B(99), B1(), B2() {}

到新的统一初始化语法,即

D() : B{99}, B1{}, B2{} {}

奇怪的事情发生了。一方面,它不再编译,出现错误

prog.cpp: In constructor ‘D::D()’:
prog.cpp:17:5: error: ‘B1::B1()’ is protected
     B1() : B(0){}
     ^
prog.cpp:31:27: error: within this context
     D() : B{99}, B1{}, B2{} {}

(对于 B2 也是如此,请参阅 here )这没有意义,因为我在派生类中使用它,所以 protected 应该没问题.如果我对此进行更正并使 B1B2 的构造函数公开而不是 protected ,那么随着输出变为

99
0
10
Final: 10

所以,其实B1s和B2s构造函数中初始化B的部分还是会被执行,甚至会改变x。这不应该是虚拟继承的情况。请记住,我唯一改变的地方

  • B1B2
  • 中的公共(public)构造函数而不是 protected 构造函数
  • D 的成员初始化列表中使用 classname{} 语法,而不是 classname()

我无法相信 gcc 中出现了这样一个基本的问题。但是我在本地机器上用 clang 对其进行了测试,所有三个案例都按预期编译和运行(即像上面的第一个示例一样)。如果这不是错误,有人可以指出我所缺少的吗?

编辑:我的第一次搜索不知何故没有出现,但现在我找到了 here ,至少显示 protected /公共(public)错误。然而,这是 gcc-4.7,所以我原以为它会在 gcc-4.8 中处理。那么,我是否应该得出结论,初始化列表在 gcc 中根本就搞砸了!?

最佳答案

我不知道现在回答这个问题是否为时已晚,但您的代码在 GCC 4.9.2 中编译得很好!

~$g++ -std=c++11 test.cpp 
~$./a.out 
99
Final: 99

~$gcc --version
gcc (GCC) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

关于c++ - gcc中的初始化列表错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26914076/

相关文章:

c++ - 如何优化多重映射的删除

c++ - 如何测试从 std::istream 读取类?

c++ - 获取释放内存顺序与顺序一致性不同的实际例子是什么?

C++11 chrono 从数字创建 time_point

c++ - 在事件对象的实现中支持 unique_ptr

c - gcc 中关于迭代 999 次的循环有什么特别之处?

c++ - 比较 string 和 LPWSTR 类型的 2 个字符串

c++ - 使用流初始化 C++ 对象

c++ - 0、int() 和 int{} 之间有什么区别?

c++ - 尝试在 Visual Studio 工作时使用 CLION 的 Boost 1.69.0,但出现奇怪的 MINGW 错误