编译时的std :: cout等效,或者c ++ 11中编译时常量值的static_assert字符串化

Jas*_*oss 18 c++ cout static-assert constexpr c++11

有没有办法在编译时打印a constexpr#defined值的值?我想要相当于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)));
Run Code Online (Sandbox Code Playgroud)

编辑:我可以用constexprs 做一些基本的编译时打印,至少在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");
Run Code Online (Sandbox Code Playgroud)

这给了我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)
Run Code Online (Sandbox Code Playgroud)

并以某种方式获得涉及4的错误消息?

je4*_*e4d 12

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

static_assert声明:

static_assert (constant-expression,string-literal);

标准说它必须是一个字符串文字,所以你运气不好; 你不能使用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);
Run Code Online (Sandbox Code Playgroud)

输出:

错误:静态断言失败:"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)
Run Code Online (Sandbox Code Playgroud)

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

至于其他编译器,我不知道你可以随意做什么,但你可能想查看boost的static_assert.hpp的副本,看看是否有任何技巧可用于获得一个评估模板arg打印.