9

**2 つの数値の累乗を実行できるように演算子を定義するにはどうすればよいですか。例えば2 ** 3。答えは 8 になるはずです。

または間接的に、#defineマクロの代わりに演算子のオーバーロードでこれを行う方法はありますか?

4

7 に答える 7

19

できません。組み込み型ではなく、既存の演算子のみをオーバーロードできます。

于 2013-10-28T10:13:21.963 に答える
10

できません。C++ では既存の演算子のみをオーバーロードできます。新しい演算子を追加したり、既存の演算子のアリティや結合性を変更したりすることはできません。ここでは、プリプロセッサでさえ無力です。その識別子をシンボルにすることはできません。

于 2013-10-28T10:13:59.470 に答える
5

指摘されている他の回答と同様に、これは組み込み型では不可能ですが、次のようなカスタム型でこれを機能させることができます(最小限のコードサンプル) :

#include <cmath>
#include <iostream>

struct dummy;

struct Int
{
    int i;
    Int() : i(0) {}
    Int(const int& i) : i(i) {}
    dummy operator*();
};

struct dummy
{
    Int* p;
    dummy(Int* const p) : p(p) {}

    int& operator*()
    {
        return p->i;
    }
};

dummy Int::operator*()
{
    return dummy(this);
}

int operator*(const Int& lhs, const dummy& rhs)
{
    return std::pow(lhs.i, rhs.p->i);
}


int main()
{
    Int a(2);
    Int b(2);
    std::cout<< a ** b << std::endl; 
}

実際の例

于 2013-10-28T11:33:11.010 に答える
5

If you're willing to make a compromise w.r.t. ** and feel like obfuscating your code:

#include <cmath>
#include <iostream>

struct foo {
    foo(int i) : i_(i) {}
    int operator*(int exp)
    {
        return std::pow(i_,exp);
    }
private:
    int i_;
};

struct bar {
} power_of;

foo operator*(int i, bar)
{
    return foo{i};
}


int main()
{
    std::cout << 2 *power_of* 3;  // prints 8
}

Otherwise, just use std::pow.

于 2013-10-28T10:25:32.367 に答える
3

他の人が指摘しているように、それは不可能です。のような別の演算子^を累乗のためにオーバーロードできますが、代わりに単純な型ラッパー クラス/オブジェクトでオーバーロードできます。

しかし、あなたが冒険好きなら、別の方法は、そのような演算子のオンザフライ計算をサポートするマイクロ DSL を作成することです。(その有名な例は C++ の LISP です)

ただし、必要な労力を考えると、それはあなたのお茶かもしれませんし、そうでないかもしれません. ただし、そのような可能性が存在することを知っておく価値があります。

アップデート:

演算子のオーバーロードは、既存の演算子をオーバーロードすることで機能します。なんで?独自に定義できる場合は、そのような演算子の優先順位も定義する必要があるため、元の目的を抽象化して演算子を悪用するのに簡単に道を譲る可能性があります。これにより、コードを読む際の困難が増します。(少なくともそれが行われた議論です)。

近い意味を持つ最も近い演算子**は、キャレット演算子です。このような演算子の素朴でわかりやすい実装は次のとおりです。

#include <iostream>
#include <cmath>

class Int {
public:
    Int() {}
    Int(int i) : value(i) {}

    friend double operator^(const int& i, const Int& integer);
    friend double operator^(const Int& integer, const int& i);
    friend double operator^(const Int& lhs, const Int& rhs);
private:
    int value;
};

double operator^ (const int& lhs, const Int& rhs) {
    return std::pow(lhs, rhs.value);
}

double operator^ (const Int& lhs, const int& rhs) {
    return std::pow(lhs.value, rhs);
}

double operator^ (const Int& lhs, const Int& rhs) {
    return std::pow(lhs.value, rhs.value);
}


int main() {
    Int i1 = 10;
    Int i2 = 3;
    double result = i1 ^ i2;

    std::cout << result;
    return 0;
}
于 2013-10-28T10:18:53.323 に答える
0

組み込み型の演算子をオーバーロードすることはできません。operator ^カスタムタイプのそのような目的で使用します。

于 2013-10-28T10:15:07.690 に答える