Tom
Tom

Reputation: 9643

c++ function in namespace won't work?

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

Answers (2)

Lily Ballard
Lily Ballard

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

Pete Becker
Pete Becker

Reputation: 76245

For Draw(shape) the compiler looks in the namespace where shapes 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

Related Questions