2010-12-15 6 views
5
namespace ns1 
{ 
    template <class T> 
    void f(T) 
    { 
     cout << typeid(T).name() << endl; 
    } 
}; 

using namespace ns1; 

namespace ns2 
{ 
    void f(int) 
    { 
     cout << "int" << endl; 
    } 

    void test() 
    { 
     f(vector<int>()); // Error! 
     // Why not call ns1::f<vector<int>>(vector<int>()); ??? 
    } 
}; 

答えて

9

これはテンプレートとは関係ありませんが、名前のルックアップはありません。

これは、標準は3.4/1で言っていることである(名前検索):

名ルックアップは(10.2を参照)の名前のための明確な 宣言を見つけるものとします。 名前ルックアップは、 が1つの宣言を関数名にする場合、1つの宣言と名前との間に1つ以上のという名前を関連付けることができます。 宣言は、 オーバーロード関数の集合(13.1)を形成すると言われています。 名前の参照が成功した後に、オーバーロードの解像度(13.3)が発生します。 アクセスルール(第11節)は、一度名前検索を行うと となり、 関数のオーバーロード解決( が該当する)が成功しました。

と3.4.1(非修飾名検索)で:

名ルックアップは、すぐ宣言は、あなたの場合は名前

のために発見されたとして終了し、fがあります修飾されていない名前。直後のスコープ内で、名前空間ns2で検索されます。この宣言はです。名前のルックアップがここで終了し、オーバーロードの解決が行われます。引数のタイプがstd::vector<int>に一致する候補セットに過負荷がないため、プログラムは不正です。

+0

をどうもありがとうございました。あなたの答えは、常に迅速かつ正確です。 – xmllmx

2

ネームスペース(ns2)内にあるときは、名前が修飾されていないと他のネームスペースより優先されます。

2

ns2は現在の名前空間であるため、ns1 :: f()の意味をコンパイラが考えるべきなのはなぜですか?

1

これは動作するはずです:

namespace ns1 
{ 
    template <class T> 
    void f(T) 
    { 
     cout << typeid(T).name() << endl; 
    } 
}; 



namespace ns2 
{ 
    using ns1::f; 
    void f(int) 
    { 
     cout << "int" << endl; 
    } 

    void test() 
    { 
     f(vector<int>()); // Error! 
     // Why not call ns1::f<vector<int>>(vector<int>()); ??? 
    } 
}; 
+0

実用的なソリューションに感謝します。 – xmllmx

関連する問題