在下面的代码中,编译器正在请求基址class X to be 默认可构造。但是,如果我删除virtual来自继承的关键字类节点, 会员的访问权限m_x当然,变得含糊不清,但是默认构造函数 for class X不再需要。
这是什么原因呢?
#include <iostream>
struct Apply
{
template< typename T >
struct Node : virtual T // this line contains the virtual inheritance
{
template< typename ...Args>
Node( Args... args )
: T( args... )
{}
};
template < typename ...BaseClasses>
struct Inheritance;
template < typename FirstBaseClass, typename ...OtherBaseClasses>
struct Inheritance< FirstBaseClass, OtherBaseClasses... > : FirstBaseClass
, Inheritance< OtherBaseClasses... >
{
template< typename ...Args>
Inheritance( Args... args )
: FirstBaseClass( args... )
, Inheritance< OtherBaseClasses... >( args... )
{
}
};
};
template < >
struct Apply::Inheritance< >
{
template< typename ...Args>
Inheritance( Args... args ){}
};
struct X
{
X(int i){}
int m_x;
};
struct A : Apply::Node< X >
{
A( int i )
: Apply::Node< X >( i )
, m_a( i )
{
}
int m_a;
};
struct B : Apply::Node< X >
{
B( int i )
: Apply::Node< X >( i )
, m_b( i )
{ }
int m_b;
};
struct C : Apply::Node< X >
{
C( int i )
: Apply::Node< X >( i )
, m_c( i )
{ }
int m_c;
};
struct Example : Apply::Inheritance< A, B, C >
{
Example( int i )
: Apply::Inheritance< A, B, C >( i )
{ }
void print( ) const
{
// this line needs the virtual inheritance
std::cout << m_x << std::endl;
std::cout << m_a << std::endl;
std::cout << m_b << std::endl;
std::cout << m_c << std::endl;
}
};
int main()
{
Example ex( 10 );
ex.print( );
return 0;
}
类的初始化顺序如下 [class.base.init]:
在非委托构造函数中,初始化按以下顺序进行:
— 首先,仅对于最底层派生类 (1.8) 的构造函数,虚拟基类在
它们在基类有向无环图的深度优先从左到右遍历中出现的顺序,
其中“从左到右”是派生类基说明符列表中基类的出现顺序。
你的层次结构是A --> Node<X> --> X
,所以首先要初始化的是X
,因为它是一个虚拟基类。它没有在您的 mem-initializer 中指定,因此插入了隐式默认构造:
A( int i )
: X() // <== implicit
, Node< X >( i )
, m_a( i )
{
}
Since X
不是默认可构造的,你会得到这个错误。您只需明确提供正确的内容即可解决此问题:
A( int i )
: X(i)
, Node< X >( i )
, m_a( i )
{
你不必担心X
被构造两次,因为虚拟基类仅为most派生类...这将是A
并不是Node<X>
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)