1

私は、BSD ファイル記述子を使用してパイプとの間で値を読み書きするコードに取り組んでいます (readおよびwrite呼び出しを使用)。これは、あるプロセスが別のプロセスにプロシージャを実行して結果を返すように指示する、単純な IPC システムの一部です。ほとんどの場合、戻り値は 1 つだけですが、いくつかのプロシージャでは複数を返す必要があります。それらのそれぞれに対して新しいことをする必要を避けるために、sstructを使用できると考えましstd::tupleた。

しかし、要素をタプルに読み込む一般的な方法を作成することにはほとんど成功しませんでした。2 つのプロセスのビット数が同じではない (1 つは 64 ビットで、もう 1 つは 32 ビット) ため、値を個別に読み取ろうとしていtupleます。非互換。これは私が試したものです:

template<typename TTupleType>
struct TupleReader
{
    int fd;
    TTupleType& storage;

    TupleReader(int fd, TTupleType& storage) : fd(fd), storage(storage)
    { }

    template<size_t Index = std::tuple_size<TTupleType>::value - 1>
    inline void Read()
    {
        Read<Index - 1>(fd);
        auto& ref = std::get<Index>(storage);
        ::read(fd, &ref, sizeof ref);
    }
};

Read<-1>インスタンス化を試み、私が使用する STL の実装が でキャッチさstd::get<-1>れるため、明らかにコンパイルされませんstatic_assert。ただし、テンプレート化された関数をクラス スコープで特殊化することは違法ですが、親structもテンプレート化されているため、メソッドを外部で特殊化することもできません。template<typename TTupleReader> void TupleReader<TTupleType>::Read<0>()部分的な専門化と見なされます。

したがって、私はこのアプローチで行き詰まっているようです。誰かがそれを行う方法を見ていますか?

4

2 に答える 2

4

インデックスを使用してみることができます:

template< std::size_t... Ns >
struct indices
{
    typedef indices< Ns..., sizeof...( Ns ) > next;
};

template< std::size_t N >
struct make_indices
{
    typedef typename make_indices< N - 1 >::type::next type;
};

template<>
struct make_indices< 0 >
{
    typedef indices<> type;
};

struct sink
{
    template<typename... T>
    sink(T&&...) {}
};

template<typename TTupleType>
struct TupleReader
{
    int fd;
    TTupleType& storage;

    TupleReader(int fd, TTupleType& storage) : fd(fd), storage(storage)
    { }

    template<size_t... Ns>
    inline void ReadImpl(const indices<Ns...>&)
    {
        sink { ::read(fd, &std::get<Ns>(storage),
                          sizeof(typename std::tuple_element<Ns,TTupleType>::type))... };
    }

    inline void Read()
    {
        ReadImpl(typename make_indices<std::tuple_size<TTupleType>::value>::type());
    }
};
于 2013-04-27T07:23:36.000 に答える