1

我正在研究使用 BSD 文件描述符从管道读取值和向管道写入值的代码(使用readandwrite调用)。这是一个简单的 IPC 系统的一部分,其中一个进程告诉另一个进程运行一个过程并返回一个结果。大多数时候只有一个返回值,但少数程序需要返回多个。为了避免不得不为struct他们每个人做一个新的,我想我可以使用std::tuples.

但是,我在创建一种将元素读入元组的通用方法方面几乎没有成功。我正在尝试单独读取这些值,因为这两个进程的位数不同(一个是 64 位,另一个是 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 的 catchstd::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 回答
0

TupleReader::Reader<i>您可以创建一个包含单个静态函数的内部模板类Read<i=0>然后,您可以根据需要为案例 部分专门化该内部类。TupleReader::Read<n>然后可以实例化TupleReader::Reader<n>并调用静态函数TupleReader::Reader<n>::Read

于 2013-04-27T13:40:53.580 回答