如何编写操作员==与隐式铸造/构造类型一起使用

How to write operator== to work with implicitly casted/constructed types

本文关键字:类型 一起 操作员 何编写      更新时间:2023-10-16

为什么这是不起作用的,因为有一个隐式'构建'的选项?

class A {};
template<typename T>
class Type {
public:
    Type() = default;
    Type(T* ptr) {
    }
};
template<typename T>
bool operator==(Type<T> l, Type<T> r) {
    return true;
}
int main() {
    A a;
    Type<A> type(&a);
    bool v = (type == &a); // Does not work
    //bool v = (type == Type<A>(&a)); // That would work
}

为什么不使用( &baseA*(的隐式构造 Type<A>

如何编写此代码以使其工作?

当检查函数模板是否可行性时,未考虑用户定义的转换。

检查函数模板是否可行性时,实现尝试根据模板参数扣除规则推导模板参数。这些规则不涉及任何类型的转换(仅类型调整,例如删除资格和参考(。如果扣除失败,候选人将被拒绝。

在您的情况下,T不能从Type<A>A推导。您需要两个参数具有相同类型的Type<X>才能成功。

您可以使操作员在类 Type中的朋友函数过载:

template<typename T>
class Type {
public:
    Type() = default;
    Type(T* ptr) {
    }
    inline friend bool operator==(Type<T> l, Type<T> r) {
        return true;
    }
};

这可以确保从声明变量Type<A> type;的那一刻开始实例化操作员。

在您的情况下,它没有实例化。调用运算符时,编译器可以创建模板的实例,但是由于模板运算符声明无法推断出参数Type<A>A*,因此会失败。这实际上是您收到的错误消息:

错误:'operator =='没有匹配(操作数类型是'type'和'a*'(

因此,Type<A>的隐式结构甚至没有考虑,因为此时存在签名bool operator==(Type<A> l, Type<A> r)

您可以定义以下其他功能模板:

template<typename T>
bool operator==(Type<T> l, T* r) {
    return l == Type<T>{r};
}

此功能模板的正文明确构造 Type<T>对象您的功能模板需要正确推断T,以便可以实例化。

这样,type == &a将导致该功能模板的实例化,从而调用您功能模板的实例化bool operator==(Type<T> l, Type<T> r)

好吧,编译器错误状态:

错误:'operator =='没有匹配(操作数类型是'type'和'a*'(

您使用typename T进行两个参数,并且由于类型不匹配,因此无法正常工作。

也考虑使用类似的东西:

template<typename T, typename U> 
bool operator==(Type<T> l, U r)
{
    return true;
}