2016-10-12 3 views
3

pre-C++ 11静的アサートを使用しようとしています。私はthisthis質問を見つけましたが、どういうわけか、私はそれが実行されている取得カント:この静的アサートが機能しないのはなぜですか?

#define STATIC_ASSERT(x) \ 
    do { \ 
     const static char dummy[(x)?1:-1] = {0};\ 
    } while(0) 

struct bar { 
    int value; 
    template<typename T> void setValue(T x); 
}; 
template<typename T> void bar::setValue(T x) { STATIC_ASSERT(1==0); } 
template<> void bar::setValue(int x) { value = x;} 

int main(){ 
    bar b; 
    int c = 1; 
    b.setValue(c);  
} 

(GCC)の結果、これをコンパイルする私は何もしてsetValueを呼び出す場合

error: size of array 'dummy' is negative

に、私はこのエラーが唯一apprearことを期待しますint以外。私は他の提案されたソリューションも試しましたが、多かれ少なかれ同じ結果が得られました。テンプレートをint以外でインスタンス化しなくても、エラーはあります。私は間違って何をしていますか?

+0

、あなたは、このような場合には、すべてのテンプレートを使用する必要はありません知っている、と単純に 'int'タイプでそれを書く興味があるだけ? (これは教育上の理由から、まだ興味深い質問と答えですが、あなたの本当の使い方が簡単ではないと思います:))。 – Ped7g

+0

@ Ped7gまあ、実際に私の実際の使用法は、例のように自明です。私は関数が正しい型のパラメータで呼び出され、変換は行われないことを絶対に確信したい。これが良いアプローチであろうとなかろうと、私はまだ確信していませんが、ここでの議論ではありません。私はcodereviewに入れます... – user463035818

+0

Explictキーワードを参照してください。 – UKMonkey

答えて

7

インスタンス化ごとにテンプレートが無効な場合、プログラムは不正な形式であり、診断は必要ありません。したがって、テンプレート引数が何であっても、setValueのプライマリテンプレートは無効であるため、GCCは完全に有効です。

この問題を解決する方法は、STATIC_ASSERTの式をテンプレートパラメータに依存させることです。 1つのオプションは、このようなdependent_falseテンプレートクラスを作ることです。

template <typename T> struct dependent_false 
{ const static bool value = false; }; 

template<typename T> void bar::setValue(T x) 
{ STATIC_ASSERT(dependent_false<T>::value); } 
+0

"特殊化が成立していない場合でも、テンプレートがすべてのインスタンス化に対して無効であれば、プログラムは不正ですか? – user463035818

+1

@ tobi303ええと... – TartanLlama

+0

それは持っていますが、あなたのハックが機能しているのがちょっと奇妙です。コンパイラが "十分に巧みな"ものであれば、彼はテンプレートがどんなものであれ矛盾していることに気付くことができます。T – user463035818

関連する問題