模板友好函数实例化

时间:2013-08-01 19:38:08

标签: c++ function templates friend friend-function

为什么我会收到以下链接器错误?

template<typename T, typename U>
class A {
public:
    class B;
};

template<typename T, typename U>
class A<T, U>::B {
    friend bool operator==(const B& b1, const B& b2);
};

template<typename T, typename U>
bool operator==(const typename A<T, U>::B& b1, const typename A<T, U>::B& b2) {
    return true;
}

int main() {
    A<char, int>::B b1;
    A<char, int>::B b2;

    if (b1 == b2) {
        return 0;
    } else {
        return 1;
    }
}

我得到的错误是:

Undefined symbols for architecture x86_64:
  "operator==(A<char, int>::B const&, A<char, int>::B const&)", referenced from:
      _main in test-qSCyyF.o

1 个答案:

答案 0 :(得分:2)

因为你正在调用它并且它没有定义!

template<typename T, typename U>
class A<T, U>::B {
    friend bool operator==(const B& b1, const B& b2);
};

A<T,U>::B类的非模板好友函数的声明。

它与调用(b1 == b2)以及您进一步定义的模板运算符匹配,但它是首选,因为它是非模板。

GCC甚至会在-Wnon-template-friend

时发出警告
  

警告:朋友声明'bool operator ==(const A :: B&amp;,const A :: B&amp;)'声明一个非模板函数[-Wnon-template-friend]
  注意:(如果这不是您的意图,请确保已声明功能模板并在此处添加&lt;&gt;之后的函数名称)

要修复,它提供定义

template<typename T, typename U>
class A<T, U>::B {
    friend bool operator==(const B& b1, const B& b2) {
        return true;
    }
};

并删除模板化运算符或仅保留模板一。