20

コンパイル時に aconstexprまたはd 値の値を出力する方法はありますか? #defineに相当する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では、次のようなことを行うことで、sを使用して基本的なコンパイル時の印刷を行うことができます

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を含むエラーメッセージが表示されますか?

4

2 に答える 2

15

§7/1 [dcl.dcl]の宣言に与えられた文法の引用 :

static_assert 宣言:

static_assert(定数式、文字列リテラル);

標準では、文字列リテラルでなければならないと言われているため、運が悪いです。constexpr 関数を使用してエラー メッセージを作成することはできません。

ただし、任意のプリプロセッサ マジックを使用して、そこに入る文字列リテラルを生成できます。PI_INTが a の代わりに #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 は 4 ではなく 3 でなければなりません」


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<4>' がネストされた名前指定子で使用されています

他のコンパイラに関しては、私はあなたが何をできるかわかりませんが、boost の static_assert.hpp のコピーを見て、そこで採用されているトリックのいずれかを使用して、評価されたテンプレート arg を出力できるかどうかを確認することをお勧めします。

于 2012-11-20T02:14:30.043 に答える