std::throw_with_nested expects polymorphic type in C++11?

旧巷老猫 提交于 2019-12-01 15:20:03

It's a bug.

When I implemented it for libstdc++ in 2009 the spec in N2619 required E to be a polymorphic type, but the final spec in the 2011 standard is different and the implementation in libstdc++ was never changed.

This would appear to be a bug.

The standard says of std::throw_with_nested:

[[noreturn]] template <class T> void throw_with_nested(T&& t);

Let U be remove_reference<T>::type.

Requires: U shall be CopyConstructible.

Throws: if U is a non-union class type not derived from nested_exception, an exception of unspecified type that is publicly derived from both U and nested_exception and constructed from std::forward<T>(t), otherwise std::forward<T>(t).

§18.8.6 [except.nested]

It does indeed look like a bug (see other answers), ref §18.8.6/7. If not already derived from std::nested_exception, an unspecified type is used that is derived from E and nested_exception.

As a proposed work around whilst it is being fixed, explicitly derive from std::nested_exception or implement the destructor as virtual;

#include <exception>

struct E : std::nested_exception { E(int) {} };
// Alternative workaround... virtual destructor
// struct E { E(int) {} virtual ~E() {} };

int main() {
 try {
  std::throw_with_nested(E(42));
  return 0;
 }
 catch (E&) {
 }
}

Sample here.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!