0

我想了解以下代码行为

#define USE_FRIEND 

class Foo
{
public:
    template <typename T>
    Foo& operator<< (T val)
    {
        std::cout << "Inside Foo" << std::endl;

        return *this;
    }
};

class A
{
public:

#ifdef USE_FRIEND
    friend Foo& operator<<(Foo& f, A& a)
    {
        std::cout << "Inside A" << std::endl;

        return f;
    }
#endif
};

int main()
{
    A a;

    Foo f;

#ifdef USE_FRIEND
    std::cout << " using Friend :: ";
#else
    std::cout << " not using Friend :: ";
#endif

    f << a;

    system("pause");
    return 0;
}

上述代码执行 2 次的输出,一次使用使用朋友,另一次不使用:

情况1:

using Friend :: Inside A

案例2:

not using Friend :: Inside Foo

我可以理解案例 2,但任何人都可以解释案例 1

4

1 回答 1

2

重载解决是一项复杂的业务,但这里有两个相关的规则:

  • 可行的重载是:

    1. template <typename T> Foo & Foo::operator<<(T)

    2. Foo & operator<<(Foo &, A &)

  • 当您调用 时,两个重载都匹配,并且它们都匹配,在模板中进行operator<<(f, a)推断。T = A准确性没有区别,因为引用算作“完美匹配”。

  • 因此,这两个重载是捆绑在一起的,并且解决方案似乎是模棱两可的。但是,有一个决胜局:1 号是模板,2 号不是。在这种情况下,非模板是更好的匹配。

于 2013-06-05T21:27:11.853 回答