GCC:当层次结构中存在虚拟继承时,C++11 内联对象初始化(使用 "this")不起作用
GCC : C++11 inline object initialization (using "this") does not work when there is a virtual inheritance in hierarchy
当在初始化中使用此指针并且在层次结构中存在虚拟继承时,C++11 内联对象初始化不起作用(在 GCC 中)。
这可能是 GCC 的错误吗(因为它在 CLang 中工作)?还是 C++11 标准本身的差距?
示例(可以在 here 中尝试),当使用 GCC 编译以下代码时:
FieldIndex m_inB{"inB", this};
没有被执行。
但是当用 CLang 编译时它会被执行。
变通方法:从 FieldIndexContainer
派生 A 作为虚拟
#include <string.h>
#include <iostream>
#include <list>
using namespace std;
class FieldIndexContainer
{
public:
class FieldIndex
{
public:
FieldIndex( const std::string& fieldName, FieldIndexContainer* owner)
{
cout << "FieldIndex called = " << fieldName << endl;
}
};
};
class A : public FieldIndexContainer
{
public:
FieldIndex m_inA{ "inA", this};
};
class Mid : virtual public A {};
class B : virtual public Mid
{
public:
FieldIndex m_inB{"inB", this};
};
int main ()
{
B* b = new B;
return 0;
}
您的 MCVE 可以进一步降低。
不需要class Mid
。 class B
可以 virtual public
继承自 class A
并且问题依然存在。
除了您提出的从 FieldIndexContainer
派生 A
的解决方法之外,作为 virtual
,代码也 在没有任何 virtual
继承的情况下也能正常工作 。
通过成员初始化,代码可以正常工作,无需任何解决方法。
参见Live Demo 2。
所以,这是一个 GCC 错误。
针对 GCC 提出了一个错误报告,标题为:Missing default initialization of member when combined with virtual inheritance,这与您在代码中观察到的非常相似。
GCC 未能调用成员 m_inB
的构造函数。在 C++ 中,不可能成功构造一个对象,但它的成员之一却没有。
这是 GCC 中的错误。
当在初始化中使用此指针并且在层次结构中存在虚拟继承时,C++11 内联对象初始化不起作用(在 GCC 中)。 这可能是 GCC 的错误吗(因为它在 CLang 中工作)?还是 C++11 标准本身的差距?
示例(可以在 here 中尝试),当使用 GCC 编译以下代码时:
FieldIndex m_inB{"inB", this};
没有被执行。 但是当用 CLang 编译时它会被执行。
变通方法:从 FieldIndexContainer
派生 A 作为虚拟
#include <string.h>
#include <iostream>
#include <list>
using namespace std;
class FieldIndexContainer
{
public:
class FieldIndex
{
public:
FieldIndex( const std::string& fieldName, FieldIndexContainer* owner)
{
cout << "FieldIndex called = " << fieldName << endl;
}
};
};
class A : public FieldIndexContainer
{
public:
FieldIndex m_inA{ "inA", this};
};
class Mid : virtual public A {};
class B : virtual public Mid
{
public:
FieldIndex m_inB{"inB", this};
};
int main ()
{
B* b = new B;
return 0;
}
您的 MCVE 可以进一步降低。
不需要class Mid
。 class B
可以 virtual public
继承自 class A
并且问题依然存在。
除了您提出的从 FieldIndexContainer
派生 A
的解决方法之外,作为 virtual
,代码也 在没有任何 virtual
继承的情况下也能正常工作 。
通过成员初始化,代码可以正常工作,无需任何解决方法。
参见Live Demo 2。
所以,这是一个 GCC 错误。
针对 GCC 提出了一个错误报告,标题为:Missing default initialization of member when combined with virtual inheritance,这与您在代码中观察到的非常相似。
GCC 未能调用成员 m_inB
的构造函数。在 C++ 中,不可能成功构造一个对象,但它的成员之一却没有。
这是 GCC 中的错误。