正确的朋友模板功能的语法

mik*_*ike 5 c++ templates friend

在"C++编程语言"第四版 - 第23.4.7章"朋友"中,我找到了以下示例(我稍微修改了它以仅显示相关部分):

template<typename T>
class Vector {
public:
    friend Vector operator*<>(const Vector& v, int f); 
                           ^^ ~~~~ ?
};

template<typename T>
Vector<T> operator*(const Vector<T>& v, int f) {
    return v;
}
Run Code Online (Sandbox Code Playgroud)

我试图编译它,但我得到以下错误(clang):

main.cpp:8:20: error: friends can only be classes or functions
        friend Vector operator*<>(const Vector& v, int f); 
                      ^
main.cpp:8:29: error: expected ';' at end of declaration list
        friend Vector operator*<>(const Vector& v, int f); 
                               ^
                               ;
2 errors generated.
Run Code Online (Sandbox Code Playgroud)

书解释说:

需要友元函数名称后面的<>来表明朋友是模板函数.如果没有<>,则假定为非模板函数.

这就是全部.

如果没有<>此代码编译,但在使用operator*时(例如Vector<int> v; v*12;),则会出现链接器错误:

main.cpp:(.text+0xb): undefined reference to `operator*(Vector<int> const&, int)'
Run Code Online (Sandbox Code Playgroud)

因此,我假设<>需要告诉编译器每次为给定类型实例化Vector模板时都应生成operator*的函数模板.

但是我在本书的例子中做错了什么,为什么?

son*_*yao 8

正如书中所说,

<>朋友功能的名称之后需要明确朋友是模板功能.

这意味着,名称应该引用一个函数模板,该模板应该事先声明(作为模板).例如

// forward declaration of the class template
template<typename T>
class Vector;

// declaration of the function template
template<typename T>
Vector<T> operator*(const Vector<T>& v, int f);

template<typename T>
class Vector {
public:
    // friend declaration
    friend Vector operator*<>(const Vector& v, int f); 
};

// definition of the function template
template<typename T>
Vector<T> operator*(const Vector<T>& v, int f) {
    return v;
}
Run Code Online (Sandbox Code Playgroud)