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

标签 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)。

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

最佳答案

N3337 [except.nested]/5,6

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

Let U be remove_reference<T>::type.
5. Requires: U shall be CopyConstructible.
6. Throws: if U is a non-union class type not derived from nested_exception, an exception of un-specified type that is publicly derived from both U and nested_exception and constructed from std::forward<T>(t), otherwise std::forward<T>(t).

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

[ Note: nested_exception has a virtual destructor to make it a polymorphic class. Its presence can be tested for with dynamic_cast. — end note ]

实际抛出的异常类型总是多态的。 U不一定是,虽然 - 只是 CopyConstructible ,如要求部分所述。

所以 libstdc++ 有一个无效的实现。它应该在内部专门针对 is_base_of<nested_exception, U>::value 的类型是false .

关于c++ - libstdc++ std::throw_with_nested() 需要多态类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26217260/

相关文章:

C++类重定义错误

c - GCC 内联汇编——与 __volatile__ 和 "memory"有什么区别?

c++ - ldd 说编译成功完成后找不到库

c++ - 通过 CRTP 检测模板类继承的元函数

c++ - 为什么编译器会选择模板参数列表中的基类构造函数?

c++ - 了解 "template argument is invalid"错误消息

c++ - VS 2015 C++ Redistributable 不在单个 DLL 中?

c++ - 在不同库中重新定义类型

c++ - 从机器名称中查找机器 IP 地址

c++ - 如何确保 lrint 在 gcc 中内联?