2017-07-25 10 views
0

pythonや他の言語で知られているべき乗演算子の実装のように、構文上の砂糖としていくつかのコードを書いていますが、演算子の定義はOKですが、演算子の署名と一致するオペランド演算子が定義されていないため、エラーが発生します。組み込み型の新しい演算子を実装する方法(コンパイラオプション)はありますか?組み込み型の演算子をオーバーロードする

#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は演算子の定義をサポートしていません。

+0

はC++には、 '**'演算子はありません、あなたはそれはPythonであなたが 'のstdを使用する必要がありますように、べき乗であることを期待している場合:: pow'または独自の関数を書く – CoryKramer

+0

@CoryKramerしかし、double型の代わりにユーザ定義型を使用し、この型に数値をキャストすると、ここで定義されたpower-operatorが動作します(実際には2つの演算子* -prefix演算子 – cmdLP

答えて

1

現在、あなたが求めていることは不可能です。組み込み関数の演算子をオーバーロードすることはできません。このため、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'; 
+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 
関連する問題