有没有办法在编译时打印constexpr
或#define
d值的值?我想要等效的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)));
编辑:我可以使用
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的错误消息,以某种方式?
最佳答案
引用§7/1 [dcl.dcl] 中声明的语法:
标准说它必须是字符串文字,所以您很不走运。您不能使用constexpr函数来构造错误消息。
但是,您可以使用任何您喜欢的预处理器魔术来生成要输入的字符串文字。如果PI_INT
是#define而不是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);
输出:编辑以响应OP的评论和更新的问题
当然,假设您很高兴依赖于特定于编译器的错误消息行为,那么一些预处理器魔术可以将其概括为:
#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)
至于其他编译器,我不知道您可以立即做些什么,但是您可能想看一下boost的static_assert.hpp副本,以查看那里使用的任何技巧都可以用来打印已评估的模板arg。
关于c++ - 在编译时等效于std::cout,或者在c++ 11中对编译时常量值进行static_assert字符串化,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13465334/