隐式转换和函数运算符

Implicit conversion and functional operators

我正在研究函数运算符,无法理解为什么像这样的代码片段可以编译:

class Pocket
{
    int value;
public:
    Pocket(int value) :value(value) {}
    int getValue() const
    {
        return value;
    }
    operator int() const
    {
        return value;
    }
    bool operator<(const Pocket & _Right) const
    {
        return value < _Right.value;
    }
};

int main() {
    Pocket mynumbers1[] = { 3, 9, 2, -4, 4 };
    Pocket mynumbers2[] = { 3, 9, 5, 0, 4 };
    vector<Pocket> v1(mynumbers1, mynumbers1 + 5);
    vector<Pocket> v2(mynumbers2, mynumbers2 + 5);
    vector<Pocket> v3(5, 0);
    transform(v1.begin(), v1.end(), v2.begin(), v3.begin(), minus<Pocket>());
    return 0;
}

我的推理是,当您在 transform 中调用 minus<Pocket> 运算符时,整个过程将简化为两个 Pocket 之间的减法。如您所见,class 没有定义适当的 operator-,只定义了 operator<,在这种情况下应该没有用,并且转换为 int,它甚至不应该考虑,因为两个参数属于同一类型。

那我错过了什么?

用户定义的转换函数,可以在您的代码中进行以下初始化:

Pocket mynumbers1[] = { 3, 9, 2, -4, 4 };
Pocket mynumbers2[] = { 3, 9, 5, 0, 4 };
当将 minus 应用于给定范围时,

也将由编译器在 transform 调用中使用:

transform(v1.begin(), v1.end(), v2.begin(), v3.begin(), minus<Pocket>());

如果您要删除 operator int() const 转换函数,则初始化和转换都不会起作用。

但是,如果您要创建转换函数 explicit,它可以用于初始化但不适用于 transform。请参阅演示 here

标准中的相关章节:

15.3.2 Conversion functions [class.conv.fct]
...
2. A conversion function may be explicit, in which case it is only considered as a user-defined conversion for direct-initialization. Otherwise, user-defined conversions are not restricted to use in assignments and initializations.