C++ 如何将数量可变的值读入std::tuple?

C++ 如何将数量可变的值读入std::tuple?,c++,c++11,metaprogramming,C++,C++11,Metaprogramming,我正在编写一段代码,它使用BSD文件描述符从管道中读取和写入值(使用read和write调用)。这是简单IPC系统的一部分,其中一个进程告诉另一个进程运行一个过程并返回一个结果。大多数情况下,只有一个返回值,但少数过程需要返回多个。为了避免为它们中的每一个都做一个新的struct,我想我可以使用std::tuples 然而,我在创建将元素读入元组的通用方法方面几乎没有成功。我试图分别读取这些值,因为这两个进程的位不相同(一个是64位,另一个是32位),而且我担心元组结构中的不同对齐要求可能会导致

我正在编写一段代码,它使用BSD文件描述符从管道中读取和写入值(使用
read
write
调用)。这是简单IPC系统的一部分,其中一个进程告诉另一个进程运行一个过程并返回一个结果。大多数情况下,只有一个返回值,但少数过程需要返回多个。为了避免为它们中的每一个都做一个新的
struct
,我想我可以使用
std::tuple
s

然而,我在创建将元素读入元组的通用方法方面几乎没有成功。我试图分别读取这些值,因为这两个进程的位不相同(一个是64位,另一个是32位),而且我担心
元组
结构中的不同对齐要求可能会导致它们不兼容。这就是我所尝试的:

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);
    }
};
模板
结构元组读取器
{
int-fd;
t类型和存储;
元组读取器(int-fd、t元组类型和存储):fd(fd)、存储(存储)
{ }
样板
内联void Read()
{
Read(fd);
auto&ref=std::get(存储);
::读取(fd和ref,sizeof ref);
}
};
它显然没有编译,因为它试图实例化
Read
,并使用
static\u assert
实现STL捕获
std::get
。但是,在类作用域中专门化模板化函数是非法的,但是由于父级
struct
也是模板化的,因此也不可能在外部专门化方法<代码>模板void TupleReader::Read()被视为部分专门化


看来我被这种方法弄得不知所措。有人找到办法了吗?

您可以尝试使用索引:

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());
    }
};
模板
结构索引
{
typedef索引next;
};
模板
结构生成索引
{
typedef typename生成索引::type::next type;
};
样板
结构生成索引<0>
{
类型定义索引类型;
};
结构水槽
{
样板
接收器(T&…{}
};
样板
结构元组读取器
{
int-fd;
t类型和存储;
元组读取器(int-fd、t元组类型和存储):fd(fd)、存储(存储)
{ }
样板
内联void ReadImpl(常量索引&)
{
接收器{::读取(fd,&std::获取(存储),
sizeof(typename std::tuple_element::type))…};
}
内联void Read()
{
ReadImpl(typename make_index::type());
}
};

您可以尝试使用索引:

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());
    }
};
模板
结构索引
{
typedef索引next;
};
模板
结构生成索引
{
typedef typename生成索引::type::next type;
};
样板
结构生成索引<0>
{
类型定义索引类型;
};
结构水槽
{
样板
接收器(T&…{}
};
样板
结构元组读取器
{
int-fd;
t类型和存储;
元组读取器(int-fd、t元组类型和存储):fd(fd)、存储(存储)
{ }
样板
内联void ReadImpl(常量索引&)
{
接收器{::读取(fd,&std::获取(存储),
sizeof(typename std::tuple_element::type))…};
}
内联void Read()
{
ReadImpl(typename make_index::type());
}
};

您可以创建一个内部模板类
TupleReader::Reader
,该类包含一个静态函数
Read
。然后,您可以根据需要对
案例的内部类进行局部专门化
TupleReader::Read
然后可以实例化
TupleReader::Reader
并调用静态函数
TupleReader::Read

您可以创建一个内部模板类
TupleReader::Reader
,该类包含一个静态函数
Read
。然后,您可以根据需要对
案例的内部类进行局部专门化
TupleReader::Read
可以实例化
TupleReader::Reader
并调用静态函数
TupleReader::Reader::Read

非常聪明。我试试看,很聪明。我试试看。