有没有办法在编译时打印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的错误消息,不知何故?
答案 0 :(得分:12)
引用§7/ 1 [dcl.dcl] 中声明的语法:
static_assert-declaration:
static_assert
(constant-expression,string-literal);
标准说它必须是一个字符串文字,所以你运气不好;你不能使用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);
输出:
错误:静态断言失败:“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&lt; 4&gt;'用于嵌套名称说明符
至于其他编译器,我不知道你可以随意做什么,但是你可能想看看boost的static_assert.hpp的副本,看看那里使用的任何技巧是否可以用来获得一个评估的模板arg印刷。