将operator ==重载为带有模板参数的自由函数的语法是什么?

| 我有一组多态类,例如:
class Apple {};
class Red : public Apple {};
class Green : public Apple {};
以及比较它们的免费功能:
bool operator==(const Apple&, const Apple&);
bool operator< (const Apple&, const Apple&);
我正在设计一个可复制的包装器类,该类将允许我将类
Red
Green
用作STL映射中的键,同时保留它们的多态行为。
template<typename Cat>
class Copy
{
public:
    Copy(const Cat& inCat) : type(inCat.clone()) {}
    ~Copy() { delete type; }
    Cat* operator->() { return type; }
    Cat& operator*() { return *type; }
private:
    Copy() : type(0) {}
    Cat* type;
};
我希望
Copy<Apples>
类型与
Apples
尽可能互换。我还必须在上面的
Copy
类中添加一些其他功能,但是现在我正在为
operator==
开发一个免费功能,如下所示:
template<typename Cat>
bool operator==(const Copy<Cat>& copy, const Cat& e) {
    return *copy == e;
}
这是我的测试代码的一部分:
Red red;
Copy<Apple> redCopy = red;
Copy<Apple> redCopy2 = redCopy;
assert(redCopy == Red());
但是编译器告诉我
../src/main.cpp:91: error: no match for ‘operator==’ in ‘redCopy == Red()’
如何识别上面的操作员==?我怀疑答案可能是在某处添加一些隐式转换代码,但我不确定该怎么做。     
已邀请:
        您的模板声明为
template <typename Cat>
bool operator==(const Copy<Cat>& copy, const Cat& e)
这与
redCopy == Red()
不匹配,因为
Red()
的类型为
Red
,因此编译器将
Red
推导为第二个参数的类型,即
Cat
=ѭ2but,但是它期望第一个参数的类型为
Copy<Red>
,但不是(
redCopy
的类型为
Copy<Apple>
)。 你真正想表达的是
template <typename Cat>
bool operator==(const Copy<Cat>& copy, const something-that-derives-from-Cat& e)
最简单的方法是添加第二个模板参数:
template <typename Cat, typename DerivedFromCat>
bool operator==(const Copy<Cat>& copy, const DerivedFromCat& e)
当然,这并不能使编译器强制DerivedFromCat实际上是从Cat派生的。如果需要,可以使用
boost::enable_if
template <typename Cat, typename DerivedFromCat>
typename enable_if<is_base_of<Cat, DerivedFromCat>, bool>::type
operator==(const Copy<Cat>&, const DerivedFromCat& e)
但这可能有点矫kill过正...     
        但是...您希望它如何工作?您声明了模板运算符
template<typename Cat>
bool operator==(const Copy<Cat>& copy, const Cat& e)
这意味着RHS上的类型与LHS上的模板参数相同(两种情况均为
Cat
)。但是您希望它在发生以下情况时被调用
redCopy == Red()
redCopy
Copy<Apple>
。怎么样? 注意:
redCopy
的模板参数是
Apple
,而不是
Red
。您的模板运算符根本无法匹配这些类型。 如果您将ѭ20声明为
Copy<Red> redCopy;
那么您的接线员就会工作。或者如果你做了
redCopy == Apple()
您的接线员也会工作。但是当您混合原始类型时
Copy<Apple> redCopy;
redCopy == Red();
它根本行不通。在这种情况下您的意图是什么?     
        @ HighCommander4解释了这里出了什么问题。另一种解决方案是禁用对“ 8”的第二个参数的推导。然后仅根据
==
运算符的第一个参数推导出第二个参数的类型:
template<typename T> struct identity { typedef T type; };

template<typename Cat>
bool operator==(const Copy<Cat>& copy, typename identity<Cat>::type const& e) {
    return *copy == e;
}
如果您这样做,则
Cat
代表什么类型就没有矛盾,
operator==
将按预期工作。     

要回复问题请先登录注册