std :: throw_with_nested期望C++ 11中的多态类型?

jot*_*tik 12 c++ exception-handling exception libstdc++ c++11

为什么这不编译(尝试使用Clang 3.4.2和GCC版本4.7.4,4.8.3和4.9.1):

#include <exception>

struct E { E(int) {} };

int main() {
  std::throw_with_nested(E(42));
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

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 'static const std::nested_exception* std::__get_nested_helper<_Ex>::_S_get(const _Ex&) [with _Ex = E]':
/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.1/include/g++-v4/bits/nested_exception.h:104:51:   required from 'const std::nested_exception* std::__get_nested_exception(const _Ex&) [with _Ex = E]'
/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.1/include/g++-v4/bits/nested_exception.h:138:38:   required from 'void std::throw_with_nested(_Ex) [with _Ex = E]'
test.cpp:6:31:   required from here
/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.1/include/g++-v4/bits/nested_exception.h:90:59: error: cannot dynamic_cast '& __ex' (of type 'const struct E*') to type 'const class std::nested_exception*' (source type is not polymorphic)
      { return dynamic_cast<const nested_exception*>(&__ex); }
                                                          ^
Run Code Online (Sandbox Code Playgroud)

Clang 3.4.2中的错误:

In file included from test.cpp:1:
In file included from /usr/lib/gcc/x86_64-pc-linux-gnu/4.9.1/include/g++-v4/exception:163:
/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.1/include/g++-v4/bits/nested_exception.h:90:16: error: 'E' is not polymorphic
      { return dynamic_cast<const nested_exception*>(&__ex); }
              ^                                     ~~~~~
/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.1/include/g++-v4/bits/nested_exception.h:104:40: note: in instantiation of member function 'std::__get_nested_helper<E>::_S_get' requested here
    { return __get_nested_helper<_Ex>::_S_get(__ex); }
                                      ^
/usr/lib/gcc/x86_64-pc-linux-gnu/4.9.1/include/g++-v4/bits/nested_exception.h:138:11: note: in instantiation of function template specialization 'std::__get_nested_exception<E>' requested here
      if (__get_nested_exception(__ex))
          ^
test.cpp:6:8: note: in instantiation of function template specialization 'std::throw_with_nested<E>' requested here
  std::throw_with_nested(E(42));
      ^
Run Code Online (Sandbox Code Playgroud)

std::throw_with_nested在C++ 11中是否期望具有多态类型的参数或者这是编译器或libstdc ++中的错误?

Jon*_*ely 16

这是一个错误.

在2009年为libstdc ++ 实现它时,N2619中的规范需要E是多态类型,但2011标准中的最终规范是不同的,并且libstdc ++中的实现从未改变过.

  • 归档为[bug 62154](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=62154). (5认同)
  • 该错误已在svn trunk中修复 (2认同)

Rob*_*ahy 8

这似乎是一个错误.

标准说std::throw_with_nested:

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

Uremove_reference<T>::type.

要求: U应该是CopyConstructible.

抛出:如果U不是衍生自非工会类类型nested_exception,未指定的类型的异常,其公开来自两个来源的Unested_exception,并从构成std::forward<T>(t),否则std::forward<T>(t).

§18.8.6[except.nested]

  • 是的,提交日志说这是我的错,虽然我不记得实现该文件了! (4认同)