Reputation: 9643
This is weird and I'm trying to find the reason why would the first call to Draw
on the object shape
is fine while the second call to Draw on the "text" field will work only when supplying the prefix of the namespace? (ie 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;
}
Upvotes: 3
Views: 121
Reputation: 185661
This is called Argument-dependent lookup. When an unqualified function is called, the compiler consults the namespaces for all of the arguments to the function and adds any matching functions to the overload set. So when you say Draw(shape)
it finds Shapes::Draw(const Shapes::Shape& shape)
based on the shape
argument. But when you say Draw("test")
, the argument "test"
has no namespace, certainly not the Shapes::
namespace that is required.
Upvotes: 2
Reputation: 76245
For Draw(shape)
the compiler looks in the namespace where shape
s type is defined to see if there's a matching function named Draw
. It finds it, and calls it. For Draw("test")
there is no namespace for the argument, so nowhere else to look. This is called argument dependent lookup, ADL for short.
Upvotes: 3