为什么转换不适用于C++中的自定义运算符?

Why doesn't conversion work with custom operators in C++?

本文关键字:自定义 运算符 C++ 转换 不适用 适用于 为什么      更新时间:2023-10-16

考虑以下代码:

class C {
  public:
    int operator-(int x) {
        return 3-x;
    }
};
class wrapper {
  public:
    operator C() {
        static C z;
        return z;
    }
} wrap;
int main() {
    return wrap-3;
}

它在g++上给出了这个错误:

test.cpp: In function ‘int main()’:
test.cpp:17:17: error: no match for ‘operator-’ in ‘wrap - 3’

转换操作员似乎在工作,因为这个版本有效:

class wrapper {
  public:
    operator int() {
        static int z=3;
        return z--;
    }
} wrap;
int main() {
    return wrap-3;
}

operator-似乎也在工作,因为这段代码编译:

class C {
  public:
    int operator-(int x) {
        return 3-x;
    }
};
int main() {
    C c
    return c-3;
}

这两者结合在一起有什么问题?为什么在隐式转换后不能应用运算符?这个问题有什么解决办法吗?

匹配成员函数时,不会对第一个操作数执行隐式转换。只需让您的运营商成为非会员,也许是朋友:
class C {
};
int operator-(C c, int x) {
    return 3-x;
}

来自[over.match.oper]:

--如果T1是一个完整的类类型,则成员候选者的集合是T1::operator@的合格查找的结果(13.3.1.1.1);否则,成员候选集合为空。

它不编译(使用GCC),因为它需要链接两个用户定义的转换才能从wrapperint:首先到C,然后到int 标准不允许这样做。请参阅David Rodriguez在另一个帖子中的回答。

当您返回wrap-3时;编译器不知道如何按顺序将包装器转换为C为了进行计算,它正在寻找一个运算符-in包装器,或者包装器中转换为数字类型。仅仅因为C有一个运算符-不要使编译器隐式转换为它,您可以在包装器中有多个转换运算符,编译器应该转换为哪一个?

要么显式地告诉编译器转换为C,要么像这样添加运算符-到包装器。。

class wrapper {
  public:
    operator C() {
        static C z;
        return z;
    }
    int operator-(int x) {
        return C()-x;
    }
} wrap;