“解包”一个数组以使用可变参数模板调用函数

时间:2016-01-21 17:02:25

标签: c++ c++11 variadic-templates

我正在使用ben strasser C ++ fast csv解析器:https://github.com/ben-strasser/fast-cpp-csv-parser。它使用可变参数模板将列值传递回处理csv数据的while循环:

io::CSVReader<2> in(csv_filename);
double x, y;
while(in.read_row(x,y)) {
    //code with x and y
}

这将调用CSVReader类中的以下函数:

template<class ...ColType>
bool read_row(ColType& ...cols){
    //snip
}

这对我的x和y值很好。但是,我想扩展它以使用任意尺寸。这意味着我的数据有一些(已知的)我需要阅读的列数。我想用这样的东西:

io::CSVReader<known_dimension> in(csvfname);
double data[known_dimension];
while(in.read_row(data)) {
    //code with data[0],data[1],...,data[known_number]
}

但是,这不是有效的语法。我需要将双打数组“解包”到指向我的双打的单独参数中。我想在不修改快速csv解析器的情况下这样做。

1 个答案:

答案 0 :(得分:5)

您可以将std::integer_sequence用于此目的:

namespace Detail
{
template <typename Reader, typename T, std::size_t... I>
void read_row(Reader& in, T* data, std::index_sequence<I...>)
{
     in.read_row(data[I]...); // A trick here
} 

}

template <std::size_t N, typename T>
void read_row(io::CSVReader<N>& in, T* data)
{
     Detail::read_row(in, data, std::make_index_sequence<N>{});
} 

当然,请这样使用:

int a[7];
io::CSVReader<7> r;
read_row(r, a);

“工作”示例:link

对于编译器“下面”C ++ 14 - integer_sequence(实际上只需要index_sequence)非常容易实现:

template <std::size_t... I>
class index_sequence {};

make_index_sequence并不那么容易 - 但也可行:

template <std::size_t N, std::size_t ...I>
struct make_index_sequence : make_index_sequence<N-1, N-1,I...> {};

template <std::size_t ...I>
struct make_index_sequence<0,I...> : index_sequence<I...> {};