C++ std::throw_with_嵌套期望为异常的虚拟基类使用默认构造函数?
为什么不编译(使用Clang 3.4.2和GCC版本4.7.4、4.8.3和4.9.1进行了尝试):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
#包括
结构基{
内联基(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
beremove\U reference::type
要求:U
应可复制
抛出:如果U
是非联合类类型,而不是从nested_exception
派生的,则是一种未指定类型的异常,该异常公开派生自U
和nested_exception
,并由std::forward(t)
构造,否则std::forward(t)
§18.8.6[嵌套的除外]
如果查看bits/nested_exception.h
,您将发现以下内容,这是库创建的基类