C++ std::throw_with_嵌套期望为异常的虚拟基类使用默认构造函数?

C++ std::throw_with_嵌套期望为异常的虚拟基类使用默认构造函数?,c++,exception,c++11,exception-handling,libstdc++,C++,Exception,C++11,Exception Handling,Libstdc++,为什么不编译(使用Clang 3.4.2和GCC版本4.7.4、4.8.3和4.9.1进行了尝试): #包括 结构基{ 内联基(int){} 虚空f(){} }; 派生结构:虚拟基{ 内联派生():基(42){} }; int main(){ std::用嵌套的(派生的())抛出; 返回0; } GCC 4.9.1中的错误: In file included from /usr/lib/gcc/x86_64-pc-linux-gnu/4.9.1/include/g++-v4/exception

为什么不编译(使用Clang 3.4.2和GCC版本4.7.4、4.8.3和4.9.1进行了尝试):

#包括
结构基{
内联基(int){}
虚空f(){}
};
派生结构:虚拟基{
内联派生():基(42){}
};
int main(){
std::用嵌套的(派生的())抛出;
返回0;
}
GCC 4.9.1中的错误:

In file included from /usr/lib/gcc/x86_64-pc-linux-gnu/4.9.1/include/g++-v4/exception:163:0,
                from test.cpp:1:
/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.1/include/g++-v4/bits/nested_exception.h: In instantiation of 'std::_Nested_exception<_Except>::_Nested_exception(_Except&&) [with _Except = Derived]':
/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.1/include/g++-v4/bits/nested_exception.h:126:60:   required from 'void std::__throw_with_nested(_Ex&&, ...) [with _Ex = Derived]'
/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.1/include/g++-v4/bits/nested_exception.h:140:58:   required from 'void std::throw_with_nested(_Ex) [with _Ex = Derived]'
test.cpp:13:35:   required from here
/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.1/include/g++-v4/bits/nested_exception.h:81:45: error: no matching function for call to 'Base::Base()'
      : _Except(static_cast<_Except&&>(__ex))
                                            ^
/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.1/include/g++-v4/bits/nested_exception.h:81:45: note: candidates are:
test.cpp:4:10: note: Base::Base(int)
  inline Base(int) {}
          ^
test.cpp:4:10: note:   candidate expects 1 argument, 0 provided
test.cpp:3:8: note: constexpr Base::Base(const Base&)
struct Base {
        ^
test.cpp:3:8: note:   candidate expects 1 argument, 0 provided
test.cpp:3:8: note: constexpr Base::Base(Base&&)
test.cpp:3:8: note:   candidate expects 1 argument, 0 provided
在/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.1/include/g++-v4/exception:163:0中包含的文件中,
来自测试。cpp:1:
/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.1/include/g++-v4/bits/nested_exception.h:在“std:::_nested_exception:::_nested_exception(_Except&&)[带_Except=Derived]”的实例化中:
/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.1/include/g++-v4/bits/nested_exception.h:126:60:从“void std::_throw_with_nested(_Ex&&,…)[with_Ex=Derived]中需要
/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.1/include/g++-v4/bits/nested_exception.h:140:58:“void std::throw_with_nested(_Ex)[with_Ex=Derived]”中的必填项
测试。cpp:13:35:从这里开始需要
/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.1/include/g++-v4/bits/nested_exception.h:81:45:错误:调用“Base::Base()”时没有匹配的函数
:_除外(静态_转换(_ex))
^
/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.1/include/g++-v4/bits/nested_exception.h:81:45:注:候选项包括:
test.cpp:4:10:note:Base::Base(int)
内联基(int){}
^
test.cpp:4:10:注意:候选者需要1个参数,提供0个参数
test.cpp:3:8:注意:constexpr Base::Base(const Base&)
结构基{
^
test.cpp:3:8:注意:候选者需要1个参数,提供0个参数
test.cpp:3:8:note:constexpr Base::Base(Base&&)
test.cpp:3:8:注意:候选者需要1个参数,提供0个参数
如果我省略了
virtual
关键字,我就不会出错。这是GCC和Clang还是libstd++错误,还是我做错了什么


注意,
virtualvoid f(){}
是一种解决方法。

问题是,当您有虚拟继承时,最后一个派生类负责构造基

在这种情况下,库试图创建更多从您的类派生的类,但无法构造它们

当您删除“虚拟”继承时,最终的类可以毫无问题地从您的继承中派生

正在命中错误消息的实现“代码”

template<typename _Except>
struct _Nested_exception : public _Except, public nested_exception 
{
  explicit _Nested_exception(_Except&& __ex)
  : _Except(static_cast<_Except&&>(__ex))
 { }
};
模板
结构嵌套异常:公共嵌套异常,公共嵌套异常
{
显式嵌套异常(&&uuuuuuex除外)
:_除外(静态_转换(_ex))
{ }
};

因此,它需要在其构造函数中构造一个
,因为它现在是最派生的类,并且不能正确地进行dp。

问题是,当您拥有虚拟继承时,最后一个派生类负责构造基

在这种情况下,库试图创建更多从您的类派生的类,但无法构造它们

当您删除“虚拟”继承时,最终的类可以毫无问题地从您的继承中派生

正在命中错误消息的实现“代码”

template<typename _Except>
struct _Nested_exception : public _Except, public nested_exception 
{
  explicit _Nested_exception(_Except&& __ex)
  : _Except(static_cast<_Except&&>(__ex))
 { }
};
模板
结构嵌套异常:公共嵌套异常,公共嵌套异常
{
显式嵌套异常(&&uuuuuuex除外)
:_除外(静态_转换(_ex))
{ }
};

因此,它需要在其构造函数中构造一个
,因为它现在是最派生的类,并且不能正确地进行dp。

问题是,当您拥有虚拟继承时,最后一个派生类负责构造基

在这种情况下,库试图创建更多从您的类派生的类,但无法构造它们

当您删除“虚拟”继承时,最终的类可以毫无问题地从您的继承中派生

正在命中错误消息的实现“代码”

template<typename _Except>
struct _Nested_exception : public _Except, public nested_exception 
{
  explicit _Nested_exception(_Except&& __ex)
  : _Except(static_cast<_Except&&>(__ex))
 { }
};
模板
结构嵌套异常:公共嵌套异常,公共嵌套异常
{
显式嵌套异常(&&uuuuuuex除外)
:_除外(静态_转换(_ex))
{ }
};

因此,它需要在其构造函数中构造一个
,因为它现在是最派生的类,并且不能正确地进行dp。

问题是,当您拥有虚拟继承时,最后一个派生类负责构造基

在这种情况下,库试图创建更多从您的类派生的类,但无法构造它们

当您删除“虚拟”继承时,最终的类可以毫无问题地从您的继承中派生

正在命中错误消息的实现“代码”

template<typename _Except>
struct _Nested_exception : public _Except, public nested_exception 
{
  explicit _Nested_exception(_Except&& __ex)
  : _Except(static_cast<_Except&&>(__ex))
 { }
};
模板
结构嵌套异常:公共嵌套异常,公共嵌套异常
{
显式嵌套异常(&&uuuuuuex除外)
:_除外(静态_转换(_ex))
{ }
};
因此,它需要在其构造函数中构造一个
Base
,因为它现在是最派生的类,并且不能正确地进行dp。

标准规定:

对于指定为虚拟的每个不同基类,最派生的对象应包含该类型的单个基类子对象

§10.1[mi类]

另外,对于
std::throw\u和\u嵌套的

[[noreturn]]模板void throw_与_嵌套(T&&T);

U
be
remove\U reference::type

要求:
U
可复制

抛出:如果
U
是非联合类类型,而不是从
nested_exception
派生的,则是一种未指定类型的异常,该异常公开派生自
U
nested_exception
,并由
std::forward(t)
构造,否则
std::forward(t)

§18.8.6[嵌套的除外]

如果查看
bits/nested_exception.h
,您将发现以下内容,这是库创建的基类