我正在尝试编写一个类模板,该模板在两个具有不同模板类型的实例之间提供比较运算符。通常情况下,该运营商是非会员朋友。我想要实现的一个简化示例如下所示。
template<typename T>
class Wrapper {
// Base type, which must have a val() method to allow comparison
T t_;
public:
Wrapper(const T& t) : t_(t) {}
// Comparison operator
template<typename B>
friend
bool
operator==(const Wrapper &a, const Wrapper<B>&b) {
return a.t_.val()==b.t_.val();
}
};
// First example type for Wrapper
class X {
int x_;
public:
X(int x) : x_(x) {}
int
val() const {return x_;}
};
// Second example type for Wrapper
class Y {
int y_;
public:
Y(int y) : y_(y) {}
int
val() const {return 2*y_;}
};
int
main() {
Wrapper<X> WX(X(4));
Wrapper<Y> WY(Y(2));
return WX==WY ? 1 : 0;
}
这个例子(g ++ 4.4.0)没有编译:相反它抱怨来自y_
的{{1}}是私有的,而且友元函数无法访问,我可以看到原因。但我该如何解决这个问题呢?为反向功能添加友谊
Wrapper<Y>
进入Wrapper类模板体只会导致编译器不明确。我不想允许Wrapper类的不同实例访问彼此的私有成员 - 我想限制对这一个操作符的访问。这可能吗?
我的笔记本电脑因为被解开而处于危险之中,因此我和笔记本电脑(以及相关的窗口)都会有任何想法。
答案 0 :(得分:2)
我的笔记本电脑是安全的(现在),因为重新阅读C++ FAQ-lite得到了帮助,尽管该示例最初似乎与我自己的问题不符。以下是通过将运算符的定义移到模板类主体之外来完成工作的:
template <typename T> class Wrapper;
template<typename A, typename B>
inline
bool
operator==(const Wrapper<A> &a, const Wrapper<B>&b) {return a.t_.val()==b.t_.val();}
template<typename T>
class Wrapper {
T t_;
public:
Wrapper(const T& t) : t_(t) {}
template<typename A, typename B>
friend
bool
operator==(const Wrapper<A> &a, const Wrapper<B>&b);
};
任何更优雅或富有洞察力的建议都将受到赞赏。
答案 1 :(得分:2)
事情数量:
当您为X
实例化一次类模板,为Y
实例化一次时,您有两个operator==
的定义。
将operator==
移出课堂声明。
请注意,friend
不是会员。因此,访问违规相关的诊断。
试试这个:
template<typename T>
class Wrapper {
// Base type, which must have a val() method to allow comparison
T t_;
public:
Wrapper(const T& t) : t_(t) {}
// Comparison operator
template<typename A, typename B>
friend bool
operator==(const Wrapper<A> &a, const Wrapper<B>&b);
};
template<typename A, typename B>
bool
operator==(const Wrapper<A> &a, const Wrapper<B>&b) {
return a.t_.val()==b.t_.val();
}
// First example type for Wrapper
class X {
int x_;
public:
X(int x) : x_(x) {}
int
val() const {return x_;}
};
// Second example type for Wrapper
class Y {
int y_;
public:
Y(int y) : y_(y) {}
int
val() const {return 2*y_;}
};
int
main() {
Wrapper<X> WX(X(4));
Wrapper<Y> WY(Y(2));
return ::operator==(WX, WY) ? 1 : 0;
}
虽然我仍然不喜欢潜伏着friend
operator==
潜伏在那里的可能性......