3

这很奇怪,我试图找出原因,为什么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;
}
4

2 回答 2

3

Draw(shape)编译器会在定义了 s 类型的命名空间中查看shape是否有一个名为 的匹配函数Draw。它找到它,并调用它。因为Draw("test")参数没有命名空间,所以无处可寻。这称为参数依赖查找,简称 ADL。

于 2013-02-15T23:35:45.700 回答
2

这称为依赖于参数的查找。当调用非限定函数时,编译器会查询函数的所有参数的命名空间,并将任何匹配的函数添加到重载集。因此,当您说它基于论点Draw(shape)找到时。但是当您说 时,参数没有命名空间,当然也不是所需的命名空间。Shapes::Draw(const Shapes::Shape& shape)shapeDraw("test")"test"Shapes::

于 2013-02-15T23:35:54.220 回答