ここでの「非依存」とは、「その特定の関数テンプレートの他のテンプレート引数に依存しない」ことを意味します。
この質問に答えている間、私は答えを見つけたと思いましたが、@Johannes (私の答えへのコメント) によると、ここで標準を誤解しています。次の簡単な例を見てください。
#include <type_traits>
template<class T>
struct X{
template<class U = typename T::type>
static void foo(int){}
static void foo(...){}
};
int main(){
X<std::enable_if<false>>::foo(0);
}
(ライブバージョンです。 )
上記がコンパイルされるという保証はありますか?GCC と Clang はここで意見が一致しません。これは、ライブ バージョンを切り替えたときに見られるようにです。興味深いことに、GCC では以下が受け入れられます。
#include <type_traits>
template<class T>
struct X{
template<bool = T::f()>
static void foo(int){}
static void foo(...){}
};
struct Y{
static bool f(){ return true; }
};
int main(){
X<Y>::foo(0);
}
(ライブバージョンです。 )
2 番目のスニペットは、静的関数が含まれているfoo(int)
場合にのみ出力されます。繰り返しになりますが、興味深いことに、完全に削除(または代わりにパス) すると、GCC は欠落しているメンバーについて不平を言い、SFINAE が許可されていないことを示します。これは前の観察と矛盾しています。Clang はすべてのバリエーションを取り、SFINAE を適用しますが、それが標準で保証されているのだろうかと思います。T
constexpr
f
f
Y
int
(FWIW、Nov CTP を使用する MSVC は一般的に Clang に同意しますが、関数が存在する場合、2 番目のスニペットでクラッシュしますconstexpr
。