4

そのテンプレート化されたクラスへの参照を取る無料の関数を定義するテンプレート化されたクラスがあります。これらの無料関数も、別のパラメーターでテンプレート化されています。

クラスの外から、無料の関数を呼び出すことができます。ただし、ある自由な関数が別の関数を呼び出すための正しい構文が見つかりません。

簡単な例:

template<typename T> class Foo {
  template<typename S>
  friend S f(const Foo &) { return S(); }

  template<typename S>
  friend S g(const Foo &s) {
    return f(s);  // See below, when instantiated, yields 'no matching function for call to f(const Foo &)'
  }
};

float test1() {
  Foo<int> o;
  return f<float>(o); // Compiles
}

float test2() {
  Foo<int> o;
  return g<float>(o); // Fails to compile as line above errors
}

このリンクも参照)

g() 内で f(s) を呼び出した時点で、最も外側のテンプレートが失われているようです。f の呼び出しで T を再指定するにはどうすればよいですか? GCC4.7、4.8、clang 3.2 をすべて同等のエラーでチェックしました。

4

1 に答える 1

6

呼び出すときは、引数から推測できないためf(s)、テンプレート パラメーターを指定する必要があります。Ss

しかし、それを変更すると(呼び出さ れf<S>(s)たときと同じテンプレート引数で呼び出すつもりであると仮定して)、ADL を禁止することになり、クラス スコープで定義されたフレンド関数を見つける唯一の方法は ADL によるものになります。そのため、グローバル名前空間に宣言を追加して、呼び出しがそれを見つけられるようにする必要があります。Sgfg

したがって、機能させるには、これらの宣言を前に追加する必要がありますFoo

template<typename T> class Foo;

template<typename S, typename T>
  S f(const Foo<T> &);

template<typename S, typename T>
  S g(const Foo<T> &);

呼び出しgを bef<S>(s)または何か他のものに変更しますf<x>(s)

于 2013-05-21T15:31:25.403 に答える