重载内置类型的运算符

时间:2017-07-25 15:07:34

标签: c++ operator-overloading

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

#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。

编辑:clang甚至不支持运营商的定义。

2 个答案:

答案 0 :(得分:2)

不,你不能重载只有参数是内置类型的运算符。即使该运营商不存在所述类型。

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

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<<你可以这样做:

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

答案 1 :(得分:1)

目前你所要求的是不可能的。您不能为内置函数重载运算符。因此,当您尝试为operator*定义一元double时,您的第一次重载是非法的。不确定为什么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';