2012-11-20 54 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