C++ 奇异函数查找
当我尝试使用std::ostream_迭代器时,我想到了下面的代码,它没有编译(在gcc 5.3或clang 3.6下)C++ 奇异函数查找,c++,c++11,operator-overloading,C++,C++11,Operator Overloading,当我尝试使用std::ostream_迭代器时,我想到了下面的代码,它没有编译(在gcc 5.3或clang 3.6下) #包括 #包括 名称空间临时{ 结构点{ int x; }; } //名称空间临时{ //名称空间标准{ std::ostream&operator我不知道您想用这条线做什么: std::ostream_iterator{std::cout} = p; 至于你的实际问题,你可以定义操作符这行有两个问题(除了没有意义之外): 首先,std::ostream\u迭代器是一个类模
#包括
#包括
名称空间临时{
结构点{
int x;
};
}
//名称空间临时{
//名称空间标准{
std::ostream&operator我不知道您想用这条线做什么:
std::ostream_iterator{std::cout} = p;
至于你的实际问题,你可以定义操作符这行有两个问题(除了没有意义之外):
首先,std::ostream\u迭代器
是一个类模板,而不是一个类
std::ostream_iterator<Point>{std::cout} = p;
或作为非会员朋友:
namespace temp {
struct Point {
int x;
friend std::ostream& operator<<(std::ostream& s, Point p) { ... }
};
}
该行出现错误,因为从call\u f
的定义来看,没有函数f()
(根本没有),而且命名空间N
中也没有函数f
。但是如果我们将f
移动到该命名空间中,两个版本都可以正常工作:
template <class T>
void call_f(T val) { f(val); }
namespace N {
struct X { };
void f(X ) { }
}
int main() {
f(N::X{}); // ok
call_f(N::X{}); // now ok too, ADL finds N::f
}
模板
无效调用_f(T val){f(val);}
名称空间N{
结构X{};
空位f(X){}
}
int main(){
f(N::X{});//好的
调用f(N::X{});//现在也可以了,ADL找到N::f
}
您观察到的行为是两阶段查找过程的一个特点,在解析模板定义中引用的名称及其与参数相关查找(ADL)的交互时使用该过程
在本例中,您使用std::ostream\u迭代器中的operator=
。从std::ostream\u迭代器::operator=
的定义中引用的名称将通过两阶段查找进行查找:在第一阶段(从operator=
的定义中)查找非依赖名称,而依赖名称则从实例化点查找(您对操作符的调用=
)
在内部,std::ostream\u迭代器::operator=
使用operator
std::ostream_iterator<Point>{std::cout} = p;
namespace temp {
std::ostream& operator<<(std::ostream& s, Point p) {
return s << p.x;
}
}
namespace temp {
struct Point {
int x;
friend std::ostream& operator<<(std::ostream& s, Point p) { ... }
};
}
std::ostream_iterator<Point>{std::cout} = p;
template <class T>
void call_f(T val) {
f(val);
}
namespace N {
struct X { };
}
void f(N::X ) { }
int main() {
f(N::X{}); // ok
call_f(N::X{}); // error: can't find 'f'
}
template <class T>
void call_f(T val) { f(val); }
namespace N {
struct X { };
void f(X ) { }
}
int main() {
f(N::X{}); // ok
call_f(N::X{}); // now ok too, ADL finds N::f
}