5

次のコードがあるとします。

template<typename T>
class A
{
public:
   T t;
};

class B
{
public:
   void foo(int i) {}

   template<typename T>
   void foo(A<T>& a) {}
};

int main()
{
   A<int> a;
   B      b;

   b.foo(a  );
   b.foo(a.t);
}

これはコンパイルして正常に動作します。の正しいオーバーロードされたバージョンが選択され、およびB::foo()に対して呼び出されます。aa.t

Cここで、から派生しB、 のテンプレート バージョンを との間で移動::foo()する新しいクラスを導入BCます。

template<typename T>
class A
{
public:
   T t;
};

class B
{
public:
   void foo(int i) {}
};

class C: public B
{
public:
   template<typename T>
   void foo(A<T>& a) {}
};

int main()
{
   A<int> a;
   C      c;

   c.foo(a  ); // Fine
   c.foo(a.t); // Error
}

そして今、コードはもうコンパイルされません。Visual Studio 2005 は次のように述べています。

error C2784: 'void C::foo(A<T> &)' : could not deduce template argument for 'A<T> &' from 'int'

C::foo()実際、任意のint値で呼び出すと、このエラーが発生します。メソッドのオーバーロードintがテンプレートのオーバーロードによって隠されているようです。

なぜこうなった?Visual Studio 2005 のコンパイラの問題ですか? 残念ながら、今のところ他のコンパイラでテストすることはできません。

どんな情報でも大歓迎です。

4

3 に答える 3

5

int のメソッド オーバーロードがテンプレート オーバーロードによって隠されているようです。

丁度!クラス C に using 宣言を追加する必要があります。

class C: public B
{
 public:
  using B::foo;
  template<typename T>
  void foo(A<T>& a) {}
};

派生クラスでメンバー関数を宣言すると、同じ名前を持つ基本クラスのすべてのメンバー関数が非表示になります。ISO/IEC 14882:2011 の §3.3.10/3 を参照してください。

派生クラスのメンバーの宣言 (第 10 節) は、同じ名前の基本クラスのメンバーの宣言を隠します。10.2 を参照してください。

于 2012-09-24T16:10:05.877 に答える
2

それは隠れていて、過負荷ではありません。使用する

class C: public B
{
public:
   using B::foo;
   template<typename T>
   void foo(A<T>& a) {}
};
于 2012-09-24T16:10:01.117 に答える
1

正解です。基本関数はhiddenです。それは実際には適切な用語です。using B::foo;のクラス定義に追加して、C非表示を解除します。

于 2012-09-24T16:11:15.570 に答える