C++将朋友添加到模板类以进行类型转换

8 c++ templates

我目前正在阅读"Effective C++",其中有一章包含与此类似的代码:

template <typename T>
class Num {
public:
  Num(int n) { ... }
};

template <typename T>
Num<T> operator*(const Num<T>& lhs, const Num<T>& rhs) { ... }

Num<int> n = 5 * Num<int>(10);
Run Code Online (Sandbox Code Playgroud)

该书说这不起作用(实际上它没有),因为你不能指望编译器使用隐式类型转换来专门化模板.

作为一个解决方案,建议使用"friend"语法来定义类中的函数.

//It works
template <typename T>
class Num {
public:
  Num(int n) { ... }

  friend 
  Num operator*(const Num& lhs, const Num& rhs) { ... }
};

Num<int> n = 5 * Num<int>(10);
Run Code Online (Sandbox Code Playgroud)

每当我需要隐式转换为模板类类型时,本书建议使用这个友元声明的东西.这一切似乎都有道理.

但是为什么我不能使用一个共同的函数,而不是一个运算符?

template <typename T>
class Num {
public:
  Num(int n) { ... }

  friend 
  void doFoo(const Num& lhs) { ... }
};

doFoo(5);
Run Code Online (Sandbox Code Playgroud)

这次编译器抱怨他根本找不到任何'doFoo'.如果我在类外声明doFoo,我会得到合理的不匹配类型错误.似乎"朋友......"部分被忽略了.

那么我的理解有问题吗?在这种情况下,函数和运算符之间有什么区别?

jua*_*nza 3

原因就在于这里

doFoo(5);
Run Code Online (Sandbox Code Playgroud)

foo给定参数,编译器无法找到int。这相当于像这样调用你的好友操作员:

Num<int> n = 5 * 10;
Run Code Online (Sandbox Code Playgroud)

这将“起作用”,但不是通过调用类friend operator*中的定义Num,而是通过调用整数的内置函数operator*,然后使用 的Num转换构造函数的隐式转换。