如何使这个操作符调用明确?

时间:2015-10-31 23:29:15

标签: c++ pointers operator-overloading smart-pointers implicit-conversion

我正在写一个智能指针作为我的学校作业,我遇到了一个问题。需要在我的智能指针和原始指针之间进行转换,所以我使用运算符重载到我的智能指针类中实现它,如下所示:

operator T*() {
    return raw_pointer;
}

另一个要求是实现==运算符,它应该在智能指针之间以及智能指针和原始指针之间工作。 我已经像这样实现了它,这个重载也可以在我的智能指针类中找到:

bool operator== (const smart_pointer<T> &smart_pointer) {
    return raw_pointer == smart_pointer.raw_pointer;
}

现在,当我尝试做这样的事情时:

smart_pointer<obj> sp = new obj();
obj *p = new obj();
if(sp == p) {
    // do something
else {
    // do something else
}

我收到以下错误消息:

ambiguous overload for 'operator=='
candidates are:
operator==(obj*, obj*) <built-in>
bool smart_pointer<T>::operator==(const smart_pointer<T>&) [with T = obj]

我想它不知道它是否应该使用内置的并将我的智能指针转换为原始指针,或者它应该使用重载==运算符的方法。问题是我目前无法想到解决这种情况的任何事情。提前谢谢!

3 个答案:

答案 0 :(得分:2)

原始指针和智能指针之间的隐式转换有点危险,这就是标准智能指针不提供它们的原因。如果你根本没有它们,那将是最好的。

那就是说,这可能不是你的选择。实际问题的解决方案是简单地添加equals运算符的更多重载,用于智能指针和原始指针之间的混合比较。那些将优先于那些需要在任何一个方向进行转换的人。

答案 1 :(得分:1)

设置构造函数或转换explicit应解决歧义:

explicit smart_pointer(T*);

explicit operator T*() const {
    return raw_pointer;
}

创建多重载是另一种替代/补充。

正如评论所指出的那样,你不希望构造函数隐含在指针的过早销毁中。

转换也是明确的,然后为不同的组合添加重载

会更好

答案 2 :(得分:1)

为每种可能的参数类型组合创建比较运算符等的重载是不切实际的。

转换为原始指针explicit本身就是一件好事,但不能解决这个问题。歧义将被解决,以便编译代码,但代价是为原始指针创建临时智能指针。在完整表达的最后,智能指针的析构函数会破坏可怜的原始指针的指示物。

因此,一般的解决方案是使每个单参数构造函数explicit,或者添加(非默认的)正式参数。