2016-01-21 79 views
3

我正在使用Ben strasser C++快速csv分析器:https://github.com/ben-strasser/fast-cpp-csv-parser。它采用了可变参数模板通过列值回while循环处理CSV数据:“解包”数组以调用具有可变参数模板的函数

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解析器进行修改的情况下执行此操作。

回答

4

您可以使用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...> {}; 
+0

虽然这是一个很好的答案,'的std :: integer_sequence'是从C++ 14 ,问题被标记为C++ 11。 – SergeyA

+0

@SergeyA - true - 我为C++添加了这个实现11 – PiotrNycz

+0

* *几乎可以工作。我收到以下错误消息:没有匹配函数调用'read_row(io :: CSVReader <2u>&,double [2])'。注意:候选是:template void read_row(io :: CSVReader &,T *)。模板参数推导/替换失败:不匹配类型long unsigned int和'#'ínteger_cst'不受dump_type支持#'。 'io :: CSVReader <2u>'不是来源于'io :: CSVReader ' –

相关问题