在这段代码中,为什么在运算符重载中无法访问我的类的私有(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/