【问题标题】:Linker error when operator== is a friend [duplicate]operator== 是朋友时的链接器错误[重复]
【发布时间】:2015-07-12 21:19:36
【问题描述】:

以下代码是重现我的问题的最少代码。当我尝试编译它时,链接器找不到operator== for Config

Undefined symbols for architecture x86_64:
"operator==(Config<2> const&, Config<2> const&)", referenced from:
          _main in test2.o

operator==Config 的朋友。但是当我不再将operator== 声明为朋友时,代码编译器没有错误。

template <int DIM>
class Config{
    // comment the following line out and it works
    friend bool operator==(const Config<DIM>& a, const Config<DIM>& b);

    public:
        int val;
};

template <int DIM>
bool operator==(const Config<DIM>& a, const Config<DIM>& b){
    return a.val == b.val;
}

int main() {
    Config<2> a;
    Config<2> b;
    a == b;
    return 0;
}

这里有什么问题?

【问题讨论】:

    标签: c++ templates linker friend


    【解决方案1】:

    您错过了在friend 声明中声明模板:

    template <int DIM>
    class Config{
        template <int DIM_> // <<<<
        friend bool operator==(const Config<DIM_>& a, const Config<DIM_>& b);
    
        public:
            int val;
    };
    

    如果你想要一个friend 函数声明,你必须使用它的精确签名声明。如果这涉及模板参数,则必须独立于封闭的模板类或结构来指定这些参数。


    这里有一个brilliant answer 深入解释friend 声明的几个方面。

    【讨论】:

    • 解决了这个问题,但我不知道为什么我必须明确地将它定义为模板。
    • @Michael 因为否则您不是在与您的模板运算符成为朋友,而是在与您的 class 模板成为朋友(并声明)某些特定的运算符 ==。
    • 友元函数只是在类之外声明它为友元的任何普通函数。现在,只需将朋友声明复制到类外,删除friend,您会发现它与您编写的模板函数不匹配。顺便说一句,我写函数是因为运算符只是一个具有特殊调用语法的函数。
    • 所以我必须告诉编译器:“请寻找 template 而不是普通的非模板函数。” ?
    • @Michael 稍微更新了我的答案。
    猜你喜欢
    • 2019-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多