2016-10-27 10 views
1

学習プロジェクトとして、私は独自のテンプレートmetaprogramming static_assertを作成しています。私はオンラインでメタプログラミングテクニックを見つけました。コンパイルに失敗するサイズ0の配列を作成しようとしました。だから私は2つのほぼ同じアプローチを使用しています:Visual Studioでは、1つは動作し、もう1つは動作しませんが、違いは何か分かりません。 g ++ 5.4.0では、どちらも動作しません( "-std = C++ 14"フラグでさえも)。何故なの?C++は独自のstatic_assertを実装しています

//This correctly aborts the compile on Visual Studio 2015. 
//But on g++ it doesn't work (not even with the "-std=c++14" flag) . 
template <bool b> 
inline void my_static_assert_function() 
{ 
    char member[b]; //if b is false, this is 0-length and fails to compile. 
} 

//On Visual Studio 2015, this does give a warning, but does not 
//abort the compile. Why not? It seems virtually identical to the 
//previous one. And on g++, it doesn't even warn. 
template <bool b> 
struct my_static_assert_struct 
{ 
    char member[b]; //if b is false, this *warns* but compiles. 
}; 

int main() 
{ 
    my_static_assert_function<1 == 2>(); //This aborts the compile, great. 
    my_static_assert_struct<1 == 2> c; //This does NOT abort the compile??? 
} 

質問#1 - 「g ++ -std = C++ 14 main.cpp」はなぜ警告なしでもコンパイルできますか? my_static_assert_functionはそこで動作するべきではありませんか?私はubuntuのために5.4.0を使用しています。

質問#2 - Visual Studio 2015では、my_static_assert_functionはコンパイルできませんが、my_static_assert_structは単なる警告でコンパイルされます。しかし、違いは何ですか?他の人がいなければ、どのように働くことができますか?

+0

GCCはトリッキー獣です。正直なコンパイラにするためには、すべてのフラグを実際に学ぶ必要があります。 –

+4

(実際のプログラマが-1の配列を作っているのはこのためです) –

+0

@Kerrek SB:GCCがエクステンションにも理由を見つけるまで。 – AnT

答えて

1

@Kerrek SBのコメントで述べたように、gccでは、標準でないISO C++拡張を使用して、ゼロサイズの配列を許可していますが、警告が表示されます。そう

#include <iostream> 
#include <type_traits> 

template<bool b, typename std::enable_if<b>::type* = nullptr> 
void my_static_assert() 
{ 
    std::cout << "Assertion OK\n"; 
} 

int main() 
{ 
    my_static_assert < (1 < 2) >(); // ok 
    //my_static_assert < (1 > 2) >(); // fails to compile 
} 

Live on Coliru

もう一つの選択肢は、(私が最初によって提案されたと思います)汎用テンプレート以外の定義を残し、そして唯一定義することであるようにはるかにエレガントな選択肢は、std::enable_if経由falseSFINAEにありますtrue専門分野。次に、falseの特殊化をインスタンス化しようとすると、不完全な型をインスタンス化できないため、コンパイル時エラーが発生します。以下の例:

template<bool> // generic 
struct my_static_assert; 

template<> 
struct my_static_assert<true>{}; 

int main() 
{ 
    my_static_assert < (1 < 2) >{}; // ok 
    my_static_assert < (1 > 2) >{}; // fails to compile 
} 

Live on Coliru

関連する問題