11

ここでの「非依存」とは、「その特定の関数テンプレートの他のテンプレート引数に依存しない」ことを意味します。

この質問に答えている間、私は答えを見つけたと思いましたが、@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 を適用しますが、それが標準で保証されているのだろうかと思います。TconstexprffYint

(FWIW、Nov CTP を使用する MSVC は一般的に Clang に同意しますが、関数が存在する場合、2 番目のスニペットでクラッシュしますconstexpr

4

1 に答える 1

3

クラステンプレートがインスタンス化されると、メンバー関数とメンバー関数テンプレートの定義部分とデフォルト引数を除いて、すべてのメンバー宣言がインスタンス化されるため、問題のコードは正しくないと思います。標準では、関数の既定の引数が正確にインスタンス化されるタイミングも定義されています。

したがって、デフォルトのテンプレート引数はすぐにインスタンス化されます。この時点でデフォルトの引数にデフォルトのテンプレート引数を含めることを意図している可能性は、私の意見では非常に小さいです。

これは、 「デフォルトのテンプレート引数は、メンバーのクラスの外に現れるクラス テンプレートのメンバーの定義のテンプレート パラメーター リストで指定してはならない」という要件に沿っています。これは、周囲のクラス テンプレートをインスタンス化するときに、そのようなテンプレート引数をすぐにインスタンス化する方法がないためです。

于 2013-03-06T22:44:17.793 に答える