ほとんどstatic_assert
の場合は で十分ですがenable_if
、タグ ディスパッチを使用すると、SFINAE の方法により、クラスのユーザーにより大きな柔軟性がもたらされます。検討:
#include <type_traits>
#include <string>
#include <iostream>
template <typename T,
class=typename std::enable_if< std::is_pod<T>::value >::type>
struct myclass
{
typedef T value_type;
T data;
};
template <typename T>
void enjoy(T)
{
std::cout << "Enjoying T!" << std::endl;
}
template <typename T>
void enjoy(typename myclass<T>::value_type)
{
std::cout << "Enjoying myclass<T>::value_type!" << std::endl;
}
int main()
{
enjoy<int>(int()); // prints: Enjoying myclass<T>::value_type!
enjoy<std::string>(std::string()); // SFINAE at work - prints: enjoying T!
myclass<int> i; // compiles OK
//myclass<std::string> s; // won't compile - explicit instantiation w/non-POD!
}
定義から2番目のテンプレート引数を削除し、myclass
代わりに他の人が提案したように、
static_assert(std::is_pod<T>::value, "POD expected for T");
クラス内の 2 行目はmain()
コンパイルに失敗し、static_assert がトリガーされます。
そうは言っても、 からのエラーはstatic_assert
、失敗した からのエラーよりも人間の観察者にとってはるかに友好的enable_if
です。だから、static_assert
あなたのために働くなら、それのために行きます. そうではなく、クラスの周りでジェネリック プログラミングをより使いやすくする必要がある場合は、次のように説明のコメントを追加することを検討してくださいenable_if
。
// POD expected for T
class=typename std::enable_if< std::is_pod<T>::value >::type>
あなたの周りの全員が C++11 に流暢でない限り。
実生活では、T がコメント テキストとコメント テキストの両方で POD でなければならない理由static_assert
を説明することをお勧めします。