在例外消息中使用constexpr

Mok*_*kaT 0 c++ exception constexpr c++11 c++14

我试图在异常消息中使用constexpr,但这不起作用:后续代码在g ++上编译得很好(使用c ++ 11或c ++ 14).

#include <exception>

constexpr auto TEST = "test";

class test_throw : public std::exception {
public:
    virtual const char* what() const throw() {
        return (std::string("THROW ")+TEST).c_str();
    }
};

int main()
{
    throw test_throw{};
} 
Run Code Online (Sandbox Code Playgroud)

我想知道为什么我的异常输出一个空消息,好吧这似乎是一个坏技巧,但我不明白消息是如何为空.

有没有办法实现这一点而不用宏替换constexpr?

Ric*_*ges 5

等待灾难 - 这是gcc的警告:

<source>: In member function 'virtual const char* test_throw::what() const':
9 : <source>:9:51: warning: function returns address of local variable [-Wreturn-local-addr]
         return (std::string("THROW ")+TEST).c_str();
Run Code Online (Sandbox Code Playgroud)

以下是一些使其安全的方法:

选项1 - 从更具体的标准异常派生,在构造函数中初始化消息.

#include <stdexcept>
#include <string>

constexpr auto TEST = "test";

class test_throw : public std::runtime_error 
{
public:
    test_throw()
    : runtime_error(std::string("THROW ")+TEST)
    {}
};
Run Code Online (Sandbox Code Playgroud)

选项2 - 以thread_safe静态方式构造消息:

class test_throw : public std::exception 
{
public:
    const char* what() const noexcept
    {
        thread_local static std::string message;

        try
        {
            message = std::string("THROW ") + TEST;
            return message.c_str();
        }
        catch(...)
        {
            return "can't give you a message";
        }
    }
};
Run Code Online (Sandbox Code Playgroud)

选项3 - 重新发明轮子.

class test_throw : public std::exception 
{
    std::string message_;

public:
    test_throw()
    : message_ { std::string("THROW ") + TEST }
    {}

    const char* what() const noexcept
    {
        return message_.c_str();
    }
};
Run Code Online (Sandbox Code Playgroud)