请考虑以下代码:
// no forward declarations
//
// template<typename T>
// class A;
//
// template<typename T>
// void swap(A<T>& lhs, A<T>& rhs);
template<typename T>
class A {
int m_i;
public:
// template<typename T1>
// friend void swap<T1>(A<T1>& lhs, A<T1>& rhs); // all instantiations of swap()
// are friends: not restrictive
// friend void swap<>(A<T>& lhs, A<T>& rhs); // restrictive: only T instantiation
// is a friend, but it requires
// forward declaration
friend void swap<>(A& lhs, A& rhs); // note absence of brackets in arguments:
// restrictive as above, but no forward
// declaration required. Why not??
A(int i = 0) : m_i{i} { }
};
template<typename T>
void swap(A<T>& lhs, A<T>& rhs) {
A<double> cA;
// cA.m_i = 0; // compile-time error: swap<int> instantiation
// is NOT a friend of A<double>
//...
}
int main() {
A<int> cA1, cA2; // A<int> instantiation
swap(cA1, cA2);
return 0;
}
上面的代码编译。
在A类中,需要前向声明的friend void swap<>(A<T>& lhs, A<T>& rhs)
似乎与friend void swap<>(A& lhs, A& rhs)
的行为方式相同,而需要前向声明。
任何人都可以解释,两者之间是否存在差异,除了一个需要前向声明,另一个不需要?它们在哪些方面与这种效果不同?