2012-09-24 8 views
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が呼び出されます。

今私はBから派生し、Bから出てC::foo()のテンプレートバージョンを移動し、新しいクラスC紹介:

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' 

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

どうしてですか? Visual Studio 2005のコンパイラに問題はありますか?残念ながら、私は他のどのコンパイラでもこれをテストすることはできません。

何か情報がありがとうございます。

答えて

5

を使用してください。

正確に!あなたはクラスCに使用して宣言を追加する必要があります。

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

あなたが派生クラスのメンバ関数を宣言すると、同じ名前の基底クラス内のすべてのメンバ関数が隠されています。 :2011:ISO/IECの§3.3.10/ 3参照14882は

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

2

これは隠れており、オーバーロードはありません。それはほとんどのintのためのメソッドオーバーロードは、テンプレートの過負荷によって隠されているように思える

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

正しく、基本機能はです。です。それは実際にはそれのための適切な用語です。表示されないようにusing B::foo;をクラス定義Cに追加します。

関連する問題