模板和自变量相关的查找
|
编译该程序时,我期望operator <<调用能够解析为全局名称空间中的那个,但是相反,编译器报告了一个模棱两可的重载。我认为非依赖查找发生在命名空间中的函数之前,这些命名空间由于参数依赖查找而被包含为潜在的匹配项。对于非模板函数,似乎是这种情况。
有人可以解释吗?
#include <iostream>
class Foo
{};
namespace NS
{
class Stream
{};
template <typename T>
Stream& operator << ( Stream& s, T t)
{
std::cerr << \"Namespace call!\\n\";
return s;
}
}
template<typename STREAM>
STREAM& operator << ( STREAM& s, Foo f )
{
std::cerr << \"Global NS call\";
return s;
}
/**
* This function (as opposed to the one above) is not ambiguous. Why?
NS::Stream& operator << ( NS::Stream& s, Foo f )
{
std::cerr << \"Global NS call\";
return s;
}
*/
int main()
{
Foo f;
NS::Stream s;
s << f;
return 0;
}
编译器输出:
test11.cpp: In function ‘int main()’:
test11.cpp:28: error: ambiguous overload for ‘operator<<’ in ‘s << f’
test11.cpp:18: note: candidates are: STREAM& operator<<(STREAM&, Foo) [with STREAM = NS::Stream]
test11.cpp:13: note: NS::Stream& NS::operator<<(NS::Stream&, T) [with T = Foo]
没有找到相关结果
已邀请:
4 个回复
骇毖煽洁铂
磐去裸猜饲
有两种可能的候选者:全局候选者和命名空间候选者之一。对于C ++编译器,在这两者之间没有选择可供选择,因此它是模棱两可的。
厘恼轨
的问题是两个参数都与一个命名空间相关联:
和
和
和
。 鉴于全局名称空间与其他名称空间一样(除了它始终在作用域内,在这里无关紧要),这两个函数重载已完全绑定在一起,以实现最佳匹配,并且编译器无法执行任何操作。 使用IOStreams库时,可以通过接受类型为“ 8”或“ 9”的参数来解决此问题,而无需进行模板参数化。
剃摧庭峨僳
中定义了
,因此存在歧义。如果在全局名称空间中定义“ 10”,则不会有歧义。 编译器将尝试根据非限定函数及其关联的命名空间的参数来解析选择哪个函数。请参阅ISO / IEC 14882:2003标准的第3.4.2节-与参数相关的名称查找。由于在全局名称空间中定义了一个参数,而在NS中定义了一个参数,因此编译器不知道要使用哪个函数。