【发布时间】:2019-03-20 02:10:21
【问题描述】:
为什么会这样:
#include <iostream>
struct base_exc : std::runtime_error
{
base_exc(const std::string& s): std::runtime_error(("base_exc: " + s).c_str()){}
};
struct derived_exc1 : base_exc
{
derived_exc1(const std::string& s): base_exc(("derived_exc1: " + s).c_str()){}
};
struct derived_exc2 : base_exc
{
derived_exc2(const std::string& s): base_exc(("derived_exc2: " + s).c_str()){}
};
template <typename T1, typename T2>
struct binary_exc: T1, T2
{
binary_exc(const std::string& s): T1(s), T2(s){}
};
int main()
{
try{
throw binary_exc<derived_exc2, derived_exc1>("something occured");
}
catch(base_exc const& e)
{
std::cout << e.what() << std::endl;
}
}
输出:
$ g++ -std=c++11 main.cpp && ./main
terminate called after throwing an instance of 'binary_exc<derived_exc2, derived_exc1>'
Aborted (core dumped)
代替:
$ g++ -std=c++11 main.cpp && ./main
base_exc: something occured
我想要实现的目标:我想为我的代码中的某些异常设置两个“正交”分类标准,例如,一个基于代码中的位置(library1_exc、library2_exc、... ) 和一个基于错误类别 (myobject1isoutofbounds_exc, myobject2isbroken_exc, .. )。
可以使用throw binary_exc<library2_exc, myobject1isoutofbounds_exc>(msg) 之类的东西抛出这些反对意见,我可以使用以下任何一种方法来捕捉它们:
- 第一个派生类
catch(library2_exc const& e) - 第二个派生类
catch(myobject1isoutofbounds_exc const& e) - 基类
catch(base_exc const& e)
我的代码在前两个之上 - 使用派生类进行捕获 - 工作正常,但最后一个没有。为什么?这里有反模式吗?
注意:
- 我阅读了Exception multiple inheritance 和https://www.boost.org/doc/libs/1_62_0/libs/exception/doc/using_virtual_inheritance_in_exception_types.html,但我无法弄清楚它们是否/如何与我的问题相关,尤其是在使用模板时。
- 我也完全可以不使用模板,但我仍然有兴趣了解为什么上面的代码不起作用。
- 对
binary_exc使用虚拟继承会产生相同的结果。 (编辑:我写票的意思是我试过struct binary_exc: virtual T1, virtual T2) - 在我看来,我的问题概括为 N>2 个继承,但让我们从 2 开始。
【问题讨论】:
-
我原以为编译器应该/会在
what调用上至少输出一个模棱两可的警告/错误。请注意,coliru 上的 Clang 只是调用终止:coliru.stacked-crooked.com/a/df03fe2c07d6a80d。 -
取出模板,发生完全相同的事情
-
虚拟继承没有同样的问题,看这里:wandbox.org/permlink/cpGIMADQBpGlPnkm
-
完美@linuxfever!我的错误是我试图在
base_exc上使用虚拟继承 - 即struct binary_exc: virtual T1, virtual T2- 而不是派生类 - 即struct derived_exc2 : virtual base_exc-。 -
确实@AlanBirtles 这与stackoverflow.com/questions/11484691/… 基本上是相同的问题,我将其标记为重复。我没有认出它可能是因为我正在使用模板。
标签: c++ templates exception-handling multiple-inheritance virtual-inheritance