20

有没有办法在编译时打印 aconstexpr或d 值的值?#define我想要相当于std::cout <<, 或某种方式来做类似的事情

constexpr int PI_INT = 4;
static_assert(PI_INT == 3,
              const_str_join("PI_INT must be 3, not ", const_int_to_str(PI_INT)));

编辑:我可以用 s 做一些基本的编译时打印constexpr,至少在 gcc 上做一些类似的事情

template <int v>
struct display_non_zero_int_value;

template <>
struct display_non_zero_int_value<0> { static constexpr bool foo = true; };

static constexpr int v = 1;

static_assert(v == 0 && display_non_zero_int_value<v>::foo, "v == 0");

这给了我error: incomplete type ‘display_non_zero_int_value<1>’ used in nested name specifier static_assert(v == 0 && display_non_zero_int_value<v>::foo, "v == 0");。(另一方面,icpc 不太有用,只是说error: incomplete type is not allowed)有没有办法编写一个可以概括这一点的宏,以便我可以做类似的事情

constexpr int PI_INT = 4;
PRINT_VALUE(PI_INT)

并以某种方式收到涉及 4 的错误消息?

4

2 回答 2

15

引用§7/1 [dcl.dcl]中为声明给出的语法 :

静态断言声明:

static_assert(常量表达式,字符串文字);

标准说它必须是字符串文字,所以你不走运;您不能使用 constexpr 函数来构造错误消息。

但是,您可以使用任何您喜欢的预处理器魔法来生成一个字符串文字。如果PI_INT是 #define 而不是 a constexpr int,则可以使用以下内容:

#define PI_INT 4
#define pi_err_str_(x) #x
#define pi_err_str(x) pi_err_str_(x)
#define pi_int_err "PI_INT must be 3, not " pi_err_str(PI_INT)

static_assert(PI_INT == 3, pi_int_err);

输出:

错误:静态断言失败:“PI_INT 必须为 3,而不是 4”


根据 OP 的评论和更新的问题进行编辑

有没有办法编写一个可以概括这一点的宏,以便我可以做类似的事情......并以某种方式获得涉及 4 的错误消息?

当然,假设您很高兴依赖于编译器特定的错误消息行为,那么一些预处理器的魔法可以概括这一点:

#define strcat_(x, y) x ## y
#define strcat(x, y) strcat_(x, y)
#define PRINT_VALUE(x) template <int> struct strcat(strcat(value_of_, x), _is); static_assert(strcat(strcat(value_of_, x), _is)<x>::x, "");

constexpr int PI_INT = 4;
PRINT_VALUE(PI_INT)

stackoverflow/13465334.cpp:20:1:错误:嵌套名称说明符中使用的类型“value_of_PI_INT_is<4>”不完整

至于其他编译器,我不知道您可以临时做什么,但您可能想查看 boost 的 static_assert.hpp 的副本,看看是否可以使用其中使用的任何技巧来打印评估的模板 arg。

于 2012-11-20T02:14:30.043 回答
0

您可以将常量表达式评估为模板的参数,其中将打印带有模板实例化名称及其参数的某种警告。

于 2022-01-11T16:31:03.023 回答