0

私のクラスNは型Tとさまざまな量の型を取りますF...

実際に起こっていることはoperator()、関数参照とその関数が提供する引数を取るためにオーバーロードしていることです。バインド機能のようなものです。しかし、関数参照が を返すとき、その関数呼び出しの値を から取得voidできるようにしたくありません。そのため、関数参照の戻り値の型が の場合に何もしないようにforのオーバーロードを追加しましたが、エラーが発生するため、関数のシグネチャを正しく書き出していないと思います。std::coutoperator()operator<<std::coutvoid

#include <iostream>
#include <utility>

template <typename T>
struct N;

template <typename T, typename ... F>
struct N<T(F...)> {
    T operator()(T (&t)(F...), F &&... f) {
        return t(std::forward<F>(f)...);
    }
};

template <typename ... T>
void operator<< (std::ostream &, const N<void(T...)> &) {}
                                 // don't do anything when void

void f(int, int) {}

int main() {

    N<void(int, int)> bind;

    std::cout << bind(f, 5, 4); // errors

}

表示されるエラーは非常に長いため、投稿しません。これらは、 を返す関数で出力する場合の典型的なエラー メッセージですvoid

を返す関数を出力しているため、上記のコードは失敗しますvoid。それが関数fです。私の過負荷はoperator<<何にも影響していないようです。ここで何が間違っていますか?さらに詳細が必要な場合は、そう言ってください。ありがとう。

4

1 に答える 1

3

operator()コードでは、 objectを明示的に呼び出していますbindbind(ちなみに、そのオブジェクトの名前を使用しないでください。std::bindあまりにも有名であり、人々を混乱させるでしょう)

コードは、あなたが要求したことを実行します。それはファンクターを呼び出しました。返されvoidた。

operator<<オーバーロードには、呼び出されたファンクターにまったく影響を与えるものはありません。

これが呼び出されたので、 -- があることがわかります。std::cout << voidこれも、あなたの とはまったく関係ありませんoperator<<

に置き換えるstd::cout << bind(f, 5, 4); // errorsstd::cout << bind;、オーバーロードoperator<<が呼び出されます。

C++ での操作の順序は、左から右ではありません。 a << b(c)最初に を評価しtmp=b(c)、次に を評価しa << tmpます。

さて、この問題を処理する方法の例は、N型を特殊化して a を返すときに、void代わりに a を返すようにすることpseudo_voidです。 のみで構成されるオーバーロードpseudo_voidがある場合を除いて、すべての使用をブロックします (ああ、常に返す必要があります)。<<return os;operator<<( ostream& os, blah )os

これにより、他の問題が発生する可能性があります。例として、「疑似 void を取り除く」特性クラスなどが必要になります。しかし、それはあなたが望む構文を提供します。

于 2012-12-22T03:55:57.593 に答える