2012-11-20 16 views
12

有没有办法在编译时打印constexpr#define d值的值?我想的std::cout <<相当于或某种方式做这样的事情在编译时std :: cout等效,或static_assert编译时常量值在C++中的字符串化11

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

编辑:我可以做这样的事情

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"); 
做一些基本的编译时间 constexpr■打印,至少在海湾合作委员会

它给我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,不知何故?

+2

没有发布这个答案,因为我没有证据可交,但我记得在过去尝试这样做,我认为标准说static_assert必须接受一个字符串字面值,因此你可以不要使用constexpr表达式。抱歉。 – je4d

+0

请注意,您的修复程序根本不使用'static_assert'。它只是重新构建了一个只会通过或失败的构造的基本思想。 “印刷”也不得不执行测试,所以你坚持用SFINAE来解决整个问题。 – Potatoswatter

回答

11

报价为声明中给出的语法§7/ 1 dcl.dcl]

static_assert-declaration:

static_assert (constant-expression , string-literal) ;

标准说,它是一个字符串,那么你的运气了;你不能使用constexpr函数来构造你的错误信息。

但是,您可以使用任何您喜欢的预处理器魔法来生成字符串文字。如果PI_INT是#定义,而不是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); 

输出:

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


编辑响应由OP评论和更新的问题

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?

当然,一点预处理或魔法可以笼统地说,假设你很高兴是依赖于特定的编译器错误消息的行为:

#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: error: incomplete type ‘value_of_PI_INT_is<4>’ used in nested name specifier

至于其他的编译器,我不知道你能做到的副手,但你可能需要查看boost的static_assert.hpp的副本,以查看是否有任何使用的技巧可用于获取打印的已评估模板arg。

+0

这回答了我的问题的最后三分之二。前三分之一,关于在编译时打印'constexpr'值并不明显。查看我刚刚编辑的内容。 –

+0

任何方式在块范围内工作(用于在模板化功能内打印)? – mxmlnkn