2013-08-13 9 views
5

メンバー関数の結果に対してアサーションを実行する必要がある汎用コードがあります。このメンバ関数はconstexprであるか、そうでないかもしれません。可能であればstatic_assertに展開するアサートマクロ?

template<typename T> 
void foo(T t) { 
    assert(t.member_function() == 10); 
} 

t.member_function()定数式であるかもしれないので、私はそれがこのような場合にstatic_assertとして扱うことが可能かどう思って、それ以外は通常のassertをデフォルトにしています。これは可能ですか?

+1

http://stackoverflow.com/q/11441302/560648と同様です。しかしそれはそれが当てはまるかどうか確信している。 –

+3

http://stackoverflow.com/q/6939103/560648はより近く、[答えは「いいえ」](http://stackoverflow.com/a/6941680/560648)です。 –

+1

[stackoverflow.com/questions/18648069] (http://stackoverflow.com/questions/18648069/g-doesnt-compile-constexpr-function-with-assert-in-it)はさらに近いと "はい" –

答えて

1

これはややクレイジーな解決策です。

Const c; foo(c);行のコメントを外してください。コンパイルされないことがわかります。これはコンパイル時のアサートです。

これはvariable length arraysを必要とし、他のコンパイラ固有のものが必要です。私はg ++上にいます - 4.6。

メンバ関数が10を返すかどうかによって、配列のサイズは0か-1のいずれかになります。コンパイル時にこれを計算できる場合、コンパイルは非可変長配列であることを認識します。それは負のサイズです。負のサイズは、それが文句を言うことができます。それ以外の場合は、従来のアサートになります。

注:ランタイムアサーションが失敗した直後に、ランタイムバージョンでコアダンプが発生します。たぶん、負のサイズの配列をfreeにしようとするのが好きではないかもしれません。アップデート:アサーションの失敗でコアダンプを取得しました。さらにint main() {assert (1==2);}です。これは正常ですか?

#include <iostream> 
#include <cassert> 
using namespace std; 

struct Const { 
     constexpr int member_function() { return 9; } 
}; 
struct Runtime { 
        int member_function() { return 9; } 
}; 

template<typename T> 
void foo(T t) { 
     if(0) { // so it doesn't actually run any code to malloc/free the vla 
      int z[(t.member_function()==10)-1]; // fails at compile-time if necessary 
     } 
     assert(t.member_function()==10); 
} 


int main() { 
     //Const c; foo(c); 
     Runtime r; foo(r); 
} 
関連する問題