为了练习,我写了一些template
函数,其名称与stl算法相同。但我的代码无法编译
错误:致电< algorithm_name>很暧昧。
我的代码中只包含using std::necessary_names;
而不是using namespace std;
。
答案 0 :(得分:2)
通常当您有using
,the "used" name takes precedence:
namespace N { int x = 0; }
int x = 1;
int main() {
using N::x;
cout << x;
}
// Output: 0
但是,依赖于参数的查找can mess this up:
namespace N {
struct T {};
void f(T) {}
}
namespace M {
void f(N::T) {}
}
int main() {
using M::f;
N::T o;
f(o); // <--- error: call of overloaded 'f(N::T&)' is ambiguous
}
所以,如果你遇到麻烦,qualify your own namespace (in this example, M
) explicitly:
namespace N {
struct T {};
void f(T) { cout << "N::f"; }
}
namespace M {
void f(N::T) { cout << "M::f"; }
}
int main() {
using M::f;
N::T o;
M::f(o); // <--- Output: "M::f"
}
有点奇怪的转折,you can also use parentheses to prevent ADL:
namespace N {
struct T {};
void f(T) { cout << "N::f"; }
}
namespace M {
void f(N::T) { cout << "M::f"; }
}
int main() {
using M::f;
N::T o;
(f)(o); // <--- Output: "M::f"
}
[n3290: 3.4.1/1]:
[re:unqualified name lookup] 在所有情况下 在3.4.1中列出,在范围内搜索声明 每个类别中列出的订单;名称查找结束 一旦找到名称的声明。如果没有声明 发现,该计划格式不正确。
[n3290: 3.4.1/2]:
[即第一优先] 来自的声明 由 using-directive 指定的命名空间在命名空间中可见 包含 using-directive ;见7.3.4。出于目的 3.4.1中描述的非限定名称查找规则,声明 从 using-directive 指定的命名空间中考虑 封闭命名空间的成员。
[n3290: 3.4.2/1]:
[re:argument-dependent lookup] 当函数调用中的 postfix-expression 时 (5.2.2)是一个 unqualified-id ,其他名称空间 通常不合格的查询(3.4.1)可能会被搜索,并在那些 名称空间,名称空间范围的朋友函数声明(11.3)不是 否则可见。这些对搜索的修改 取决于参数的类型(以及模板模板) 参数,模板参数的名称空间。)。
即。正常查找将停止在您使用using
进入范围的名称中,但是当ADL进入游戏时,其他名称也会添加到候选集中,从而导致两个名称之间存在歧义。
答案 1 :(得分:0)
最好在namespace
中声明自己的版本;这样就不会发生这样的问题。
namespace MySTL
{
template<typename T, ... > // ... means other template params
class vector;
template<typename T, ... >
class queue;
...
}
现在你可以做到,
using std::vector;
不会与MySTL::vector
发生冲突。
答案 2 :(得分:0)
您可能会遇到Argument Dependent Lookup的问题。将名称空间中定义的类型传递给非限定函数时,所有参数的名称空间都会隐式添加到查找集中,这可能会导致冲突。您可以尝试限定自己的算法调用以禁止ADL进入。
namespace n {
struct test {};
void foo( test const & ) {}
};
int main() {
n::test t;
foo( t ); // Will find n::foo as the argument belongs to n namespace
}