在编译时等效于std :: cout,或c ++ 11中编译时常量值的static_assert字符串化 [英] std::cout equivalent at compile time, or static_assert stringification of compile-time constant values in c++11

查看:90
本文介绍了在编译时等效于std :: cout,或c ++ 11中编译时常量值的static_assert字符串化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以在编译时打印 constexpr #define d值?我想要等价于 std :: cout<< 或某种方式做类似的事情

Is there a way to print the value of a constexpr or #defined value at compile time? I want the equivalent of std::cout <<, or some way to do something like

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)));

编辑:我可以使用<$做一些基本的编译时打印c $ c> constexpr s,至少在gcc上执行类似

I can do some basic compile-time printing with constexprs, at least on gcc by doing something like

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

这给我错误:不完整的类型'display_non_zero_int_value< 1>'用于嵌套名称说明符static_assert(v == 0& display_non_zero_int_value< v> :: foo, v == 0); 。 (另一方面,icpc的帮助较小,只是说 error:不允许不完整的类型)有没有一种方法可以编写可以将其概括化的宏我可以做类似的事情

which gives me 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, on the other hand, is less helpful, and just says error: incomplete type is not allowed) Is there a way to write a macro that can generalize this so that I can do something like

constexpr int PI_INT = 4;
PRINT_VALUE(PI_INT)

并收到一条包含4的错误消息? p>

and get an error message that involves 4, somehow?

推荐答案

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

Quoting the grammar given for declarations in §7/1 [dcl.dcl]:


static_assert-declaration:

static_assert-declaration:

static_assert (constant-expression,string -literal);

static_assert ( constant-expression , string-literal ) ;

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

The standard says it has to be a string literal, so you're out of luck; you can't use a constexpr function to construct your error message.

但是,您可以使用任何喜欢的预处理器魔术来生成字符串常量。如果 PI_INT 是#define而不是 constexpr int ,则可以使用以下方式:

You can, however, use whatever preprocessor magic you like to generate a string literal to go in there. If PI_INT is a #define instead of a constexpr int, you could use something like this:

#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

error: static assertion failed: "PI_INT must be 3, not 4"




编辑以回复评论由OP和更新的问题


Edit in response to comment by OP and updated question


有没有一种方法可以编写一个可以对此进行概括的宏,以便我可以执行类似...的操作并收到错误消息肯定涉及到4?

Is there a way to write a macro that can generalize this so that I can do something like ... and get an error message that involves 4, somehow?

当然,假设您很高兴依靠编译器特定的错误消息,则可以使用一些预处理器魔术来概括这一点行为:

Sure, a bit of preprocessor magic can generalize that, assuming you're happy to be reliant on compiler-specific error message behaviour:

#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>'

stackoverflow/13465334.cpp:20:1: error: incomplete type ‘value_of_PI_INT_is<4>’ used in nested name specifier

对于其他编译器,我不知道您可以立即使用,但是您可能需要查看boost的static_assert.hpp副本,以查看那里使用的任何技巧都可以用来打印已评估的模板arg。

As for other compilers, I don't know what you can do offhand, but you may want to look at a copy of boost's static_assert.hpp to see if any of the tricks employed there can be used to get an evaluated template arg printed.

这篇关于在编译时等效于std :: cout,或c ++ 11中编译时常量值的static_assert字符串化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆