Static_assert——一种动态定制错误消息的方法

static_assert - a way to dynamically customize error message

本文关键字:错误 消息 动态 方法 assert Static 一种      更新时间:2023-10-16

是否有办法使static_assert的字符串动态自定义,然后显示?
我的意思是:

//pseudo code
static_assert(Check_Range<T>::value, "Value of " + typeof(T) + " type is not so good ;)");

不,没有。

然而,这并不重要,因为static_assert是在编译时求值的,如果出现错误,编译器不仅会打印出消息本身,而且还会打印实例化堆栈(在模板的情况下)。

看一下ideone中的合成例子:

#include <iostream>
template <typename T>
struct IsInteger { static bool const value = false; };
template <>
struct IsInteger<int> { static bool const value = true; };
template <typename T>
void DoSomething(T t) {
  static_assert(IsInteger<T>::value, // 11
  "not an integer");
  std::cout << t;
}
int main() {
  DoSomething("Hello, World!"); // 18
}

编译器不仅发出诊断,而且还发出完整的堆栈:

prog.cpp: In function 'void DoSomething(T) [with T = const char*]':
prog.cpp:18:30:   instantiated from here
prog.cpp:11:3: error: static assertion failed: "not an integer"

如果你知道Python或Java,知道它们是如何在异常情况下打印堆栈的,你应该很熟悉。事实上,它甚至更好,因为您不仅获得了调用堆栈,还获得了参数值(这里是类型)!

因此,动态消息不是必需的:)

标准指定static_assert的第二个参数为字符串字面量,因此据我所知,没有机会在那里进行计算(除了预处理器宏)。

编译器可以扩展标准并允许在此位置使用适当类型的const-表达式,但我不知道是否有编译器这样做。

正如Matthieu所说,这是不可能的,但您可以通过使用宏获得一些您正在寻找的功能:

#define CHECK_TYPE_RANGE(type)
    static_assert(Check_Range<type>::value, "Value of " #type " type is not so good ;)");
CHECK_TYPE_RANGE(float); // outputs "Value of float type is not so good ;)"