用朋友减少冗长

时间:2016-02-26 20:29:06

标签: c++ templates operator-overloading friend

使用friend在类定义中定义全局函数被认为是一种好习惯,即使不需要访问私有成员也是如此。例如

template<typename T>
class A {
public:
    A(T v);
    T value() const;

    friend A operator+(T n, const A& a) {
        return A(a.value() + n);
    }
};

而不是

template<typename T>
class A {
public:
    A(T v);
    T value() const;
};

template<typename T>
A<T> operator+(T n, const A<T>& a) {
    return A<T>(a.value() + n);
}

即使operator+仅使用公开的value()。 这是常见的,我们不建议使用吗?

1 个答案:

答案 0 :(得分:4)

这里friend有一个主要优势。当我们定义:

friend A operator+(T, const A&);

这是的功能模板。这只是一个功能 - 一个只能由ADL找到的特殊功能。但由于它不是功能模板,转换仍然可能发生。另一方面:

template <class T>
A<T> operator+(T, const A<T>&)

是一个普通的旧函数模板,其中包含有关模板类型推导的所有常规规则。

为什么这很重要?考虑:

A<double> a(4.2);
5 + a;

在第一种情况下,这非常好。我们发现operator+(double, const A<double>&)5转换为5.0,这是允许的转换,我们会返回A<double>(9.2)

在第二种情况下,模板推导失败,因为T推导出两个参数的不同类型。因此,代码是不正确的。