Ответ 1
Это ошибка.
Когда я реализовал его для libstdС++ в 2009 году, спецификация в N2619 потребовала E
для быть полиморфным типом, но окончательная спецификация в стандарте 2011 года отличается и реализация в libstdС++ никогда не изменялась.
Почему это не компилируется (используется с версиями 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;
}
Ошибки из 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); }
^
Ошибки от 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));
^
Есть ли std::throw_with_nested
в С++ 11 аргумент с полиморфным типом или это ошибка в компиляторе или libstdС++?
Это ошибка.
Когда я реализовал его для libstdС++ в 2009 году, спецификация в N2619 потребовала E
для быть полиморфным типом, но окончательная спецификация в стандарте 2011 года отличается и реализация в libstdС++ никогда не изменялась.
Это может показаться ошибкой.
В стандарте говорится о std::throw_with_nested
:
[[noreturn]] template <class T> void throw_with_nested(T&& t);
Пусть
U
beremove_reference<T>::type.
Требуется:
U
должно бытьCopyConstructible
.Выдает: if
U
- это тип неединичного класса, не полученный изnested_exception
, исключение неопределенного типа, которое открыто выводится как изU
, так иnested_exception
и построено изstd::forward<T>(t)
, в противном случаеstd::forward<T>(t)
.§18.8.6 [except.nested]
Это действительно выглядит как ошибка (см. другие ответы), ref §18.8.6/7. Если он еще не получен из std::nested_exception
, используется неуказанный тип, полученный из E
и nested_exception
.
Как предлагаемая работа вокруг, в то время как она фиксируется, явно получается из std::nested_exception
или реализует деструктор как виртуальный;; p >
#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&) {
}
}
Пример здесь.