2013-08-01 106 views
1

为什么我在下面得到链接器错误?模板好友功能实例化

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 

回答

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

警告的警告:朋友宣言 '布尔运算符==(const的一个:: B &,常量一个:: B &)' 声明一个非模板函数[ - Wnon模板,朋友]
注:(后这里的函数名,如果这不是您的本意,请确保该函数模板已经声明,并添加<>)

要解决,它提供定义

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

并摆脱模板操作符或只保留一个模板。

+0

那么...我该如何解决它。 = P – fumoboy007

+0

我认为这将是obvius :)我会更新。 – jrok

+0

所以我不能有一个模板化的朋友函数,它是在类之外定义的? – fumoboy007