1

foo()一部の関数をに変更しようとしていますがoperator<<()、単に「半分 C/半分 C++」コードを C++ のように見せるためです。ただし、次の変換ステップで行き詰まりました。

template <class... T>
inline const size_t foo(const T&... data) {
    return sizeof...(T);
}
struct bar {
    template <class... T>
    inline const size_t operator<<(const T&... data) {
        return sizeof...(T);
    }
};
int main(int argc, char *argv[]) {
    bar a;
    std::cout << ">>> length " << foo(1, 2, 3) << std::endl;
    std::cout << ">>> length " << (a << 1 << 2) << std::endl;
    std::cout << ">>> length " << (a << 1 << 2 << 3) << std::endl;
    std::cout << ">>> length " << (a << 1 << 2 << 3 << 4) << std::endl;
}

出力から:

$ ./a.out 
>>> length 3
>>> length 4
>>> length 32
>>> length 512

最初の計算は に対して実行されa << 1、それに応じて後続の値がシフトされると結論付けています。それでも、のユーザーにインターフェイスfoo()を提供するために を書き直す方法がわかりません。もちろん、セマンティクスを変更することはありません。operator<<() struct barfoo()

class T...パラメータとしてに渡す方法がない場合、関数は何度も呼び出されるため、operator<<()当然、 よりも効率が悪くなります。foo()これには妥当な C++ 構造がありますか、それとも固執することfoo()が唯一の/最良のオプションですか?

コンテキスト:

これらのfoo()機能は、ネットワーク通信の送信者/受信者です。通常の関数を使用する以外に、送信者/受信者ストリーム、書き込み可能/読み取り可能な使用<<および演算子を備えた、より「C++」なインターフェイスを提供する方がよいと思いました。>>foo(...)

4

1 に答える 1

5

言語は、あなたが求めていることを実行しています。

結合性がある場合、以下は同等です (<<>>左から右への結合):

a << 1 << 2
(a << 1) << 2

この呼び出しa << 1は、ユーザー定義の演算子を呼び出します。これは、 を返しますsize_t。そのため、次の呼び出しの型は次のとおりです: size_t << int(これは単純なビット単位のシフトです)。

式テンプレートを使用する必要があります。アイデアは次のとおりです(ライブの例はこちら):

template<typename... args>
struct stream_op
{
};

template<typename... A, typename B>
stream_op<A..., B> operator<<(stream_op<A...> a, B b)
{
    // Do stuff
}

したがって、次のことが発生します ( aas a を使用stream_op<>):

a << 1 << 2
------
  |
  v
-------------------------------------------
stream_op<int> operator<<(stream_op<>, int) << 2
--------------                                ---
     |                                         |
     |             +---------------------------+
     v             v
--------------    ---
stream_op<int> << int
--------------    ---
       |           |
       |           +---------------------------+
       +----------------------------+          |
                                    v          v
                              --------------  ---
stream_op<int,int> operator<<(stream_op<int>, int)
------------------
        |
        v
------------------
stream_op<int,int> // <- Expected result

stream_op次に、int(または必要なもの)に変換するメソッドを配置するだけです。

パフォーマンスに関する注意: これらの式テンプレートでは、データの一部が型にエンコードされるため、通常は を直接呼び出すのと同じくらい高速foo(...)です。

于 2013-07-25T21:39:24.017 に答える