这很奇怪,我试图找到为什么第一次调用对象Draw
上的shape
是正常的,而第二次调用“文本”字段上的Draw将会有效只有在提供命名空间的前缀时? (即Shapes::Draw
):
#include <iostream>
namespace Shapes
{
class Shape {
public:
Shape() {}
virtual void InnerDraw() const {
std::cout << "Shape\n";
}
};
class Square : public Shape {
public:
void InnerDraw() { std::cout << "Square\n"; }
};
void Draw(char* text) { std::cout << text; }
void Draw(const Shape& shape) {
Draw("Inner: ");
shape.InnerDraw();
}
Shape operator+(const Shape& shape1,const Shape& shape2){
return Shape();
}
}
int main() {
const Shapes::Square square;
Shapes::Shape shape(square);
Draw(shape); // No need for Shapes::
Draw("test"); // Not working. Needs Shapes:: prefix
return 0;
}
答案 0 :(得分:3)
对于Draw(shape)
,编译器查找名称空间,其中定义了shape
类型,以查看是否存在名为Draw
的匹配函数。它找到它并称之为。对于Draw("test")
,参数没有命名空间,因此无处可寻。这称为参数依赖查找,简称ADL。
答案 1 :(得分:2)
这称为Argument-dependent lookup。当调用非限定函数时,编译器会查询函数的所有参数的名称空间,并将任何匹配函数添加到重载集。因此,当您说Draw(shape)
时,它会根据Shapes::Draw(const Shapes::Shape& shape)
参数找到shape
。但是当你说Draw("test")
时,参数"test"
没有命名空间,当然不是所需的Shapes::
命名空间。