【问题标题】:overloading operators of builtin types [duplicate]重载内置类型的运算符
【发布时间】:2017-07-25 15:07:34
【问题描述】:

虽然我正在编写一些代码作为语法糖,例如在 python 和其他语言中已知的 power-operator 的实现,但操作符定义是可以的,但是操作数与操作符签名匹配的表达式会产生错误,因为从未定义过运算符。有没有办法(编译器选项)为内置类型实现新的运算符?

#include <iostream>
#include <cmath>

    template<typename t_Float>
struct PowerTmp {
    t_Float value;
};

PowerTmp<double> operator*(double f) {
    return {f};
};

double operator*(double l, PowerTmp<double> r) {
    return std::pow(l, r.value);
};

int main() {
    std::cout << 10.5 *PowerTmp<double>{2.0} << '\n';
    cout << 10.5 ** 2.0 << '\n'; //error
};

我正在使用 mingw。

EDIT:clang 甚至不支持运算符的定义。

【问题讨论】:

  • C++ 中没有 ** 运算符,如果您希望它像 Python 中那样进行求幂运算,您应该使用 std::pow 或编写自己的函数
  • @CoryKramer 但是,当使用用户定义的类型而不是 double 并将数字转换为这种类型时,此处定义的幂运算符起作用(它实际上是两个运算符,*-前缀运算符和乘法运算符!)

标签: c++ operator-overloading


【解决方案1】:

不,您不能重载唯一参数是内置类型的运算符。即使该类型不存在该运算符。

您可以做的是创建一个中间类型。例如:

struct EnhancedDouble {
    double d;
};

struct PowPrecursor {
    double d;
};

PowPrecursor operator*(EnhancedDouble b) {
    return { b.d };
}

EnhancedDouble operator*(EnhancedDouble lhs, PowPrecursor rhs) {
    return { std::pow(lhs.d, rhs.d) };
}

您甚至可以使用用户定义的文字对其进行更多修饰。

EnhancedDouble operator""_ed(long double d) {
    return { (double)d };
}

输入operator&lt;&lt;,您可以这样做:

std::cout << 4.0_ed ** 4.0_ed; // prints 256

【讨论】:

    【解决方案2】:

    你所问的目前是不可能的。您不能为内置函数重载运算符。因此,您的第一个重载是非法的,因为您试图为 double 定义一元 operator*。不知道为什么 gcc 不抱怨。

    但是,您可以使用 UDL 来“更改”文字的类型。下面是一个用于演示的简化示例:

    struct Exponent { long double value; };
    struct PowerDouble { long double value; };
    
    Exponent operator""_exp(long double exponent) {
        return{exponent};
    }
    
    PowerDouble operator*(Exponent f) {
        return{f.value};
    }
    
    long double operator*(long double l, PowerDouble r) {
        return std::pow(l, r.value);
    }
    
    long double operator*(long double l, Exponent r) {
        return l * r.value;
    }
    

    那么你可以这样使用它:

    std::cout << 10.5 ** 2._exp << '\n';
    std::cout << 10.5 * 2._exp << '\n';
    

    【讨论】:

    • 请注意,10.5 * 2._exp 也将执行幂运算。 10.5 ***** 2._exp 也一样。
    • @BenjaminLindley 你是对的,已修复:) 谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-19
    • 1970-01-01
    • 2016-01-25
    • 1970-01-01
    • 2015-01-29
    相关资源
    最近更新 更多