在模板类中编写友元函数声明的正确方法是什么?

Mar*_* Lu 5 c++ templates vector friend

我正在尝试编写自己的向量模板类,但是在编写友元函数声明时遇到了一些问题。

一开始我是这样写的:

template <typename T, typename Alloc = std::allocator<T>>
class vector {
public:
    friend bool operator==(const vector<T, Alloc>&, const vector<T, Alloc>&);
};
Run Code Online (Sandbox Code Playgroud)

但是编译器报告了一个警告,我声明了一个非模板函数。所以我把朋友声明改成了这样:

template <typename T, typename Alloc = std::allocator<T>>
class vector {
public:
    template <typename E, typename F>
    friend bool operator==(const vector<E, F>&, const vector<E, F>&);
};
Run Code Online (Sandbox Code Playgroud)

到目前为止一切都很好,但我认为仍然存在问题。如果我这样写,我会创建所有operator==将两个模板参数作为其友元函数的函数。例如,operator==(const vector<int>&, const vector<int>&)andoperator==(const vector<double>&, const vector<double>&)都是vector<int>的友元函数。

在模板类中编写友元函数的正确方法是什么?

son*_*yao 5

友元非模板函数

但是编译器报告了一个警告,我声明了一个非模板函数。

是的,您在类定义中声明了一个非模板函数。这意味着如果您在类定义之外定义它,则必须将其定义为非模板函数,并且对于所有可能的实例化,例如:

bool operator==(const vector<int>& v1, const vector<int>& v2)
{
    ...
}
bool operator==(const vector<char>& v1, const vector<char>& v2)
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

这很难看,您可以在类定义中定义它,例如

template <typename T, typename Alloc = std::allocator<T>>
class vector {
public:
    friend bool operator==(const vector<T, Alloc>&, const vector<T, Alloc>&) {
        ...
    }
};
Run Code Online (Sandbox Code Playgroud)

友元函数模板

如果你想将其定义为模板函数,并限制友谊的范围,你可以

// forward declaration
template <typename T, typename Alloc>
class vector;

// forward declaration
template <typename T, typename Alloc>
bool operator==(const vector<T, Alloc>& v1, const vector<T, Alloc>& v2);

template <typename T, typename Alloc = std::allocator<T>>
class vector {
private:
    int i;
public:
    // only the instantiation of operator== with template parameter type of current T and Alloc becomes friend
    friend bool operator==<>(const vector<T, Alloc>& v1, const vector<T, Alloc>& v2);
};

template <typename T, typename Alloc = std::allocator<T>>
bool operator==(const vector<T, Alloc>& v1, const vector<T, Alloc>& v2)
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

然后, for vector<int>, onlybool operator==(const vector<int>&, const vector<int>&)是朋友,其他实例化bool operator==(const vector<double>&, const vector<double>&)则不是。

居住