1

<<これが機能するように演算子をオーバーロードすることは可能ですか?

void f (int f)
{
}

int main ()
{
    f << 2;
}

これが機能するためには、何を勉強する必要がありますか?

4

3 に答える 3

3

次のような電話をかけたい場合

f << arg1 << ... << argN;

~と同じように振る舞う

f(arg1, ..., argN);

次に、次のC++11コードが必要なことを行います。

このように呼び出したい関数ごとに、関数で呼び出される引数を保持する「プロキシ オブジェクト」を作成しますf。このオブジェクトは、必要な引数が 1 つ少ない新しい「プロキシ オブジェクト」を返す必要があります。良い副作用: これは、引数のカリー化に使用できます。

実行例を含む完全なコードは次のとおりです: http://ideone.com/NFtnuT

簡単に言うと、このコードは次のことを行います: 可変個引数のテンプレート引数を持つテンプレート クラスを定義します。

template<class R, /* ... */>
class ProxyFunction
{
    // Underlying function:
    std::function<R(/* ... */)> f;

public:
    ProxyFunction(std::function<R(/* ... */)> f) : f(f) {}

    ProxyFunction<R, /* one arg less */> operator <<(/* one argument */) {
         /* create new proxy function with one argument less */
    }
};

最後の引数については、破棄時または戻り値の型にキャストするときに、基になる関数を呼び出す必要がありますR/*...*/これは、実際には何もない場合のテンプレート クラスを部分的に特殊化することによって行われます。

コードは次のように呼び出されます。

// Create proxy function. You can pass f around as you want.
auto f = makeProxy(/* underlying "real" function */);

// Call f using this syntax, discarding the result:
f << a << b;

// Use its result:
int result = f << a << b;

これの良いところは、カリー化をサポートしていることです:

auto g = (f << a);      // Bind first parameter, but don't call yet.
int result = (g << b);  // Bind second parameter, now call it.
于 2013-02-12T09:34:45.023 に答える
2

演算子のオーバーロードは、オペランドの少なくとも 1 つがユーザー定義(クラス型または列挙型) を持つ場合にのみ有効です。おそらく、次のように定義できます。

?? operator<<( void (*f)( int ), MyType );

MyType列挙型またはクラス型のいずれかです (ただし、ではありません int)。C++ では、<<フォーマット データ (最終的な出力用) と左シフト (どちらも左側のオペランドの状態を意味する) という 2 つの確立された意味があります。関係のないことをするためにオペレーターに過負荷をかけることは、過負荷の悪用を操作しています。読者が を見たとき、<<ある種の書式設定またはシフトが行われていると想定する権利があります。関係のないことを過負荷<<にすると、彼は混乱します。

于 2013-02-12T09:32:41.203 に答える
2

fオーバーロードされたクラスのインスタンスである必要があるoperator <<か、オーバーロードされた演算子を持つ型のオブジェクトを返す必要があります (ただし、それを呼び出す必要がありますf())。

struct F
{
   F& operator << (int x) { return *this; }
};

//...
F f;
f << 2;
于 2013-02-12T08:56:40.003 に答える