重载运算符== 作为具有模板化参数的自由函数的语法是什么?
What's the syntax to overload operator== as a free function with templated parameters?
我有一组多态类,例如:
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
= Red
,但是它期望第一个参数的类型是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)
但这可能有点矫枉过正...
但是...你期望它如何工作?您声明了模板运算符
template<typename Cat>
bool operator==(const Copy<Cat>& copy, const Cat& e)
这意味着 RHS 上的类型与 LHS 上的模板参数相同(在两种情况下都是Cat
(。然而,您希望在以下情况下调用它
redCopy == Red()
redCopy
在哪里Copy<Apple>
.如何?
注意:redCopy
的模板参数是 Apple
,而不是 Red
。模板运算符根本不可能匹配这些类型。
如果您redCopy
声明为
Copy<Red> redCopy;
然后您的操作员将工作。或者如果你这样做了
redCopy == Apple()
您的操作员也可以工作。但是当您混合像原始类型一样
时Copy<Apple> redCopy;
redCopy == Red();
它根本行不通。在这种情况下,您的意图是什么?
@HighCommander4解释了这里出了什么问题。另一种解决方案是禁用 operator==
的第二个参数的扣除。然后仅根据==
运算符的第一个参数推导第二个参数的类型:
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==
将按预期工作。
- 如何反转整数参数包
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 如何使用默认参数等选择模板专业化
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 函数调用中参数的顺序重要吗
- 部分定义/别名模板模板参数
- 模板-模板参数推导:三个不同的编译器三种不同的行为
- 使用不带参数的函数访问结构元素
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 如何在OMNET++中指定与命令行参数组合的输出文件名
- 如何将成员函数作为回调参数传递给需要"typedef-ed"自由函数指针的函数?
- 返回的通用lambda的参数据称是自由功能的阴影参数
- 为什么未调用自由函数作为构造函数中的参数传递
- 使用自由模板参数传递模板类型名称
- 为什么我们可以检测 SFINAE 中 operator() 的默认参数值的存在,而不是自由函数和 PMF 的默认参数值
- 重载运算符== 作为具有模板化参数的自由函数的语法是什么?
- 用显式参数检测自由函数的存在性