static_assert - 一种动态自定义错误消息的方法

问题描述 投票:0回答:4

有没有办法让static_assert的字符串动态定制然后显示?
我的意思是这样的:

//pseudo code
static_assert(Check_Range<T>::value, "Value of " + typeof(T) + " type is not so good ;)");
c++ c++11 static-assert
4个回答
12
投票

不,没有。

但是这并不重要,因为

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 以及它们如何在异常情况下打印堆栈,那么应该很熟悉。但事实上,它甚至更好,因为您不仅可以获得调用堆栈,还可以获得参数值(此处的类型)!

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


10
投票

标准将

static_assert
的第二个参数指定为字符串文字,因此据我所知,没有机会进行计算(预处理器宏除外)。

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


8
投票

正如 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 ;)"

0
投票

C++26 或许还有希望。 C++26 草案改变了 C++23

static_assert-declaration:
    static_assert ( constant-expression ) ;
    static_assert ( constant-expression , string-literal ) ;

static_assert-message:
    unevaluated-string
    conditional-expression

static_assert-declaration:
    static_assert ( constant-expression ) ;
    static_assert ( constant-expression , static_assert-message ) ;

希望这能成功。

© www.soinside.com 2019 - 2024. All rights reserved.