Why does "using namespace xxx" not take effect on template functions?
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>>(ve开发者_JAVA百科ctor<int>()); ???
}
};
This has nothing to do with templates, but without name lookup.
This is what the standard says in 3.4/1 (name lookup) :
Name lookup shall find an unambiguous declaration for the name (see 10.2). Name lookup may associate more than one declaration with a name if it finds the name to be a function name; the declarations are said to form a set of overloaded functions (13.1). Overload resolution (13.3) takes place after name lookup has succeeded. The access rules (clause 11) are considered only once name lookup and function overload resolution (if applicable) have succeeded.
And in 3.4.1 (unqualified name lookup) :
name lookup ends as soon as a declaration is found for the name
In your case, f
is an unqualified name. It is searched in the immediate scope, and in namespace ns2
where a declaration is found. Name lookup ends here, and overload resolution comes into play : there is no overload in the candidate set which matches the argument type std::vector<int>
, so the program is ill-formed.
Because when you're inside a namespace (ns2) it takes precedence over any others if names are unqualified.
ns2 will take priority as that is the namespace you are currently in. Why should the compiler think that you really meant ns1::f() ?
This should work :
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>()); ???
}
};
精彩评论