use*_*302 1 c++ templates copy-constructor friend-function
当友元函数 mag() 在类内部定义时,下面显示的代码不会编译,但如果在类外部定义(已注释),则可以工作。我认为差异是由用于将参数类型从 A 更改为 B 的复制构造函数引起的。有人可以解释为什么我应该在外部定义友元函数吗?
而且,如果B类是模板类(template <class T>
在最上面添加),在外面定义友元函数也是不行的。
#include <iostream>
using namespace std;
class A {
};
class B {
public:
B(const A& p) {
std::cout << "Copy/Conversion constructor" << std::endl;
}
friend void mag(const B& p) {
std::cout << "Mag Inside`.\n";
}
};
//void mag(const B& p) {
// std::cout << "Mag Outside.\n";
//}
int main() {
A a;
mag(a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
因为该函数mag
没有在全局作用域中声明(当您同时将其设为友元时,您确实定义并声明了它,但仍然需要在其自己的作用域中声明)。
您需要声明它:
class B {
public:
B(const A& p) {
std::cout << "Copy constructor" << std::endl;
}
friend void mag(const B& p) {
std::cout << "Mag Inside`.\n";
}
};
void mag(const B& p);
Run Code Online (Sandbox Code Playgroud)
如果您使用对象调用mag
,B
参数依赖查找将查找B
的范围并找到定义。
现在 ifB
是一个模板,您需要使用mag
适当的参数声明每个版本(如果存在多个版本,您需要帮助编译器解决转换期间的歧义):
template<typename T>
class B {
public:
B(const A& p) {
std::cout << "Copy constructor" << std::endl;
}
friend void mag(const B<T>& p) {
std::cout << "Mag Inside`.\n";
}
};
void mag(const B<int>& p); // Version for B<int> declared.
Run Code Online (Sandbox Code Playgroud)