C++20 格式的异常消息

Nic*_*els 5 c++ c++20 stdformat

类似于这个问题。需要使用类似 printf 的风格而不是字符串串联或 iostreams 来抛出异常和消息。使用 C++ 20 格式化库:

  throw std::runtime_error { 
    std::format("Critical error! Code {}: {}", errno, strerror(errno)) 
  }; 
Run Code Online (Sandbox Code Playgroud)

但在所有带有格式化的异常中,感觉调用格式都不符合人体工学,可以变得更好吗?

Nic*_*els 3

是的,它可以!

#include <format>
#include <stdexcept>

class runtime_exc : public std::runtime_error
{
   public:
     template <class... Args>
     runtime_exc(std::format_string<Args...> what_arg_fmt, Args&&... args)
       : runtime_error { std::format(what_arg_fmt, args...) }
     {
        
     }
};
Run Code Online (Sandbox Code Playgroud)

用法:

  throw runtime_exc { "Critical error!" };          
  throw runtime_exc {                        
    "Critical error! Code {}: {}", errno, strerror(errno) 
  };                                       
Run Code Online (Sandbox Code Playgroud)

如果您在运行时以格式组装消息,则可以使用std::vformat. 如果需要语言环境,您可以添加另一个构造函数并将其作为第一个参数。注意std::format可以扔。

编辑:巴里评论,无需移动格式字符串并转发参数。

  • _注意 std::format 可能会抛出异常。_如果确实如此,则坏消息... (4认同)
  • `runtime_exc` 本身可能被认为是不必要的。只需要一个模板函数来构造格式化字符串(如此代码所示,使用“std::format”),并且返回构造的“std::runtime_error”(打哈欠,无聊),或者也进行抛出。调用站点看起来像 `if (errno) throw_runtime_error("坏狗,没有饼干!{}: {}", errno, strerror(errno));` (2认同)