2017-07-25 100 views
0

雖然我將一些代碼編寫爲像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。

編輯:clang甚至不支持運算符的定義。

+0

有一個在C++中沒有'**'經營者,如果你期待的是要冪像Python中,你應該使用'STD :: pow'或編寫自己的函數 – CoryKramer

+0

@CoryKramer但是,當使用用戶定義的類型而不是double並將數字轉換爲此類型時,此處定義的權力運算符起作用(它實際上是兩個運算符,即* -prefix運算符和乘法運算符!) – cmdLP

回答

1

你現在要問的是不可能的。您不能爲內置插件重載運算符。因此,您的第一次過載是非法的,因爲您正在嘗試爲double定義一元operator*。不知道爲什麼海灣合作委員會不抱怨。

但是,您可以使用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'; 
+0

請注意,對此,「10.5 * 2._exp」也將執行冪運算。就像'10.5 ***** 2._exp'一樣。 –

+0

@BenjaminLindley你是對的,修好:)謝謝 – Rakete1111

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