Kyl*_*yle 4 c++ templates operator-overloading non-member-functions
我有一组多态类,例如:
class Apple {};
class Red : public Apple {};
class Green : public Apple {};
Run Code Online (Sandbox Code Playgroud)
以及比较它们的免费功能:
bool operator==(const Apple&, const Apple&);
bool operator< (const Apple&, const Apple&);
Run Code Online (Sandbox Code Playgroud)
我正在设计一个可复制的包装类,它允许我在STL映射中使用类Red和Green键,同时保留它们的多态行为.
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;
};
Run Code Online (Sandbox Code Playgroud)
我希望这种Copy<Apples>类型尽可能地互换Apples.还有一些我必须添加到Copy上面的类中的函数,但是现在我正在使用一个自由函数operator==,如下所示:
template<typename Cat>
bool operator==(const Copy<Cat>& copy, const Cat& e) {
return *copy == e;
}
Run Code Online (Sandbox Code Playgroud)
这是我的测试代码的一部分:
Red red;
Copy<Apple> redCopy = red;
Copy<Apple> redCopy2 = redCopy;
assert(redCopy == Red());
Run Code Online (Sandbox Code Playgroud)
但编译器告诉我
../src/main.cpp:91: error: no match for ‘operator==’ in ‘redCopy == Red()’
Run Code Online (Sandbox Code Playgroud)
如何让它识别我的算子==以上?我怀疑答案可能是在某处添加一些隐式转换代码,但我不知道该怎么做.
您的模板声明为
template <typename Cat>
bool operator==(const Copy<Cat>& copy, const Cat& e)
Run Code Online (Sandbox Code Playgroud)
这是不匹配的,redCopy == Red()因为Red()是类型的Red,所以编译器推断Red为第二个参数的类型,即Cat= Red,但是它然后它期望第一个参数的类型Copy<Red>,它不是(redCopy的类型是Copy<Apple>).
你真正想要表达的是什么
template <typename Cat>
bool operator==(const Copy<Cat>& copy, const something-that-derives-from-Cat& e)
Run Code Online (Sandbox Code Playgroud)
最简单的方法是添加第二个模板参数:
template <typename Cat, typename DerivedFromCat>
bool operator==(const Copy<Cat>& copy, const DerivedFromCat& e)
Run Code Online (Sandbox Code Playgroud)
当然,这并没有让编译器强制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)
Run Code Online (Sandbox Code Playgroud)
但这可能有点矫枉过正......