libstdc ++ std :: throw_with_nested()需要多态类型

时间:2014-10-06 13:27:37

标签: c++ gcc c++11 clang libc++

考虑以下(我认为非法)代码:

#include <exception>
#include <string>

using namespace std;

int main()
{
    try {
        try {
            throw string ("x");
        }
        catch(string& x)
        {
            throw_with_nested(string("xx"));
        }
    }
    catch(...)
    {
        auto ep = current_exception();
    }

    return 0;
}

使用clang ++针对libc ++编译此代码编译。

使用g ++反对libstdc ++:

In file included from /usr/local/gcc-4.8.1/include/c++/4.8.1/exception:153:0,
                 from main.cpp:1:
/usr/local/gcc-4.8.1/include/c++/4.8.1/bits/nested_exception.h: In instantiation of �static const std::nested_exception* std::__get_nested_helper<_Ex>::_S_get(const _Ex&) [with _Ex = std::basic_string<char>]�:
/usr/local/gcc-4.8.1/include/c++/4.8.1/bits/nested_exception.h:104:51:   required from �const std::nested_exception* std::__get_nested_exception(const _Ex&) [with _Ex = std::basic_string<char>]�
/usr/local/gcc-4.8.1/include/c++/4.8.1/bits/nested_exception.h:138:38:   required from �void std::throw_with_nested(_Ex) [with _Ex = std::basic_string<char>]�
main.cpp:15:43:   required from here
/usr/local/gcc-4.8.1/include/c++/4.8.1/bits/nested_exception.h:90:59: error: cannot dynamic_cast �& __ex� (of type �const class std::basic_string<char>*�) to type �const class std::nested_exception*� (source type is not polymorphic)
       { return dynamic_cast<const nested_exception*>(&__ex); }
                                                           ^

据我了解,std::throw_with_nested<T>要求T是多态的,而std :: string不是多态的。所以libstdc ++在这里正在做正确的事(tm)。

这里有什么可以提供的吗?

1 个答案:

答案 0 :(得分:3)

  

N3337 [except.nested] / 5,6

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

U成为remove_reference<T>::type
5.要求:U   CopyConstructible
6.抛出:如果U不是非联合类类型   派生自nested_exception,是从Unested_exception公开派生并由std::forward<T>(t)构建的未指定类型的例外,否则为std::forward<T>(t)

还要考虑nested_exception是多态的,因为它有一个虚拟析构函数([except.nested] / 2):

  

[注意:nested_exception有一个虚拟析构函数来实现它   多态类。可以使用dynamic_cast测试其存在。    - 结束说明]

实际抛出的异常类型总是多态的。但U并非如此 - 只需CopyConstructible,如需要部分所述。

因此libstdc ++的实现无效。它应该在内部专门针对is_base_of<nested_exception, U>::valuefalse的类型。