c++ - 无法访问模板化重载运算符中的私有(private)成员

标签 c++ templates operator-overloading overloading friend

在这段代码中,为什么在运算符重载中无法访问我的类的私有(private)字段?

(请注意,这只是一个 MRE,不是完整代码)

template <typename T>
class Frac

template <typename T, typename U>
Frac<T> operator+ (Frac<T> lhs,const Frac<U>& rhs);

template <typename T, typename U>
bool operator==(const Frac<T>& lhs, const Frac<U>& rhs);

template <typename T>
class Frac {

    template<typename>
    friend class Frac;

    friend Frac operator+ <>(Frac lhs,const Frac& rhs);

    friend bool operator== <>(const Frac& lhs, const Frac& rhs);

    private:
        T numerator, denominator;
};

template <typename T, typename U>
Frac<T> operator+(Frac<T> lhs,const Frac<U>& rhs) {
    lhs.denominator += rhs.denominator;
    return lhs;
}

template <typename T, typename U>
bool operator==(const Frac<T>& lhs, const Frac<U>& rhs) {
    return (lhs.numerator == rhs.numerator && lhs.denominator == rhs.denominator);
}

当我编译时,编译器告诉我不能访问分母和分子字段,因为它们是私有(private)的。但是,过载被指示为友好。该类也被指示为友好的,因此无论类型如何,该类的所有实例都是友好的。

谁能解释一下问题是什么以及如何解决?

最佳答案

制作每个实例

template <typename T, typename U>
bool operator==(const Frac<T>& lhs, const Frac<U>& rhs);

friend ,您需要在 friend 中一样冗长。声明。复制此声明并在其中粘贴“friend”。有两个怪癖。一、template必须在 friend 之前来,因此您将在声明的中间添加关键字。二、T已被用作类的模板参数,因此您应该选择不同的标识符以避免遮蔽(我将使用 S)。

    template <typename S, typename U>
//                    ^^^
    friend bool operator==(const Frac<S>& lhs, const Frac<U>& rhs);
//  ^^^^^^                           ^^^

如果没有这个变化,你是说 Frac<T> 的 friend 是一个运算符,它需要两个 Frac<T>参数(相同的 T )。

关于c++ - 无法访问模板化重载运算符中的私有(private)成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70628865/

相关文章:

C++11 在同一线程中执行 block 但超时

c++ - 内联模板函数的编译错误

c++ - 虚拟运算符 float()

c++ - FindResource 在 exe 文件上给出错误 1813

c++ - 拦截 COM dllhost.exe 调用

c++ - 一般情况下需要模板参数完整的情况是什么?

c++ - 用于 pod 的重载运算符 ==

c++ - 函数作为 std::function 包装器的构造函数的参数

pointers - 通过指针访问类型后派生类型中 Fortran 字符串的奇怪行为

c++ - 如何输出乘以用户创建的类c++