1語:SFINAE。
代替エラーはエラーではありません。
グーグルでその言葉を探して、まったく新しい世界があなたのために開きます。
あなたのコードの意味を見てみましょう。
std::is_integral<typename T>::value
T
は、そうでない場合は、整数型、false
ある場合は値true
を持つタイプT
から依存ブール値、です。
std::enable_if<bool B, typename T = void>::type
それはタイプT
、B == true
、そうでない場合は何もないのです。だから、
、あなたのコード内
template < class T,
class = typename std::enable_if<std::is_integral<T>::value>::type>
T
が整数型であるとき、第二(無名の)テンプレート引数は、タイプ(デフォルトで置換されている:void
;しかし、この場合では、正確な型無関係です)、機能が有効になります。逆に、T
が整数型でない場合、2番目のテンプレート引数の置換に失敗し、このバージョンのis_even()
関数はアクティブ化されていません(タイプT
)。これが重要な点です。エラーではありません(is_even()
の別のバージョンを有効にすることができます)。
is_even()
の代替バージョンを実装する方法をもっと興味深く見ることができます。あなたはstd::is_integral
template < class T,
class = typename std::enable_if<false == std::is_integral<T>::value>::type>
を否定するが、これは動作しません別のバージョンを実装することができますことを考えることができますが、引数がポイントのテンプレートから(異なっ2つのis_even()
テンプレート機能を持っているので、(エラーであり、コンパイルされません)ビューのデフォルトの引数のみ)。
ソリューションを使用すると、非整数型の積分型であり、第2版(そのリターンさえfalse
)のために有効にis_even()
のバージョンを持っている。このようにして、戻り値
#include <type_traits>
#include <iostream>
template <typename T>
typename std::enable_if<true == std::is_integral<T>::value, bool>::type
is_even (T const & i)
{ return ! (i%2); }
template <typename T>
typename std::enable_if<false == std::is_integral<T>::value, bool>::type
is_even (T const &)
{ return false; }
int main()
{
std::cout << "-- is 7 even ? " << is_even(7) << '\n';
std::cout << "-- is 8UL even ? " << is_even(8LL) << '\n';
std::cout << "-- is \"abc\" even ? " << is_even("abc") << '\n';
return 0;
}
にSFINAEを適用することができます。
p.s .:申し訳ありませんが、私の悪い英語です。
デフォルトのテンプレートパラメータで、名前はありません。主な「その他のユースケース」はコンストラクタテンプレートにあります。コンストラクタには戻り値の型がないからです。 –