使用Boost zip_iterator将两个向量写入CSV文件

时间:2018-02-15 12:18:18

标签: c++ c++03 boost-iterators

我有两个向量,我想以CSV格式写入文件。我可以使用for循环“手动”执行此操作,但我第一次尝试使用boost zip_iterator。这是我能走多远。 (online version

请注意,这是遗留项目的,因此我无法使用较新版本的C ++(例如C ++ 11,C ++ 14,C ++ 17)

#include <vector>
#include <fstream>
#include <iterator>
#include <algorithm>
#include <boost/tuple/tuple.hpp>
#include <boost/iterator/zip_iterator.hpp>

typedef boost::tuples::tuple<unsigned,unsigned> DataPair;
typedef std::ostream_iterator<DataPair> DataPairOStream;

// Error messages suggest that something resembling this overload might be needed.
// This however does not solve the problem.
DataPairOStream& operator<<( DataPairOStream& stream , const DataPair& )
{
    return stream;
}

int main()
{
    std::vector<unsigned> data1( 10 , 1 );
    std::vector<unsigned> data2( 10 , 2 );

    std::ofstream outputFile( "Foo.txt" );
    DataPairOStream outputIterator( outputFile , "\n" );   // ???

    std::copy(
        boost::make_zip_iterator( boost::make_tuple( data1.begin() , data2.begin() ) ) ,
        boost::make_zip_iterator( boost::make_tuple( data1.end()   , data2.end()   ) ) ,
        outputIterator ); 
}

错误消息的片段(整个过程太长而无法粘贴)

/usr/lib/gcc/i686-pc-cygwin/6.4.0/include/c++/bits/stream_iterator.h:198:13: error: no match for ‘operator<<’ (operand types are ‘std::ostream_iterator<boost::tuples::tuple<unsigned int, unsigned int> >::ostream_type {aka std::basic_ostream<char>}’ and ‘const boost::tuples::tuple<unsigned int, unsigned int>’)
  *_M_stream << __value;
  ~~~~~~~~~~~^~~~~~~~~~

2 个答案:

答案 0 :(得分:2)

这个应该很好用。现在ADL发现operator<<重载,因为它放在名称空间boost::tuples中:

#include <vector>
#include <fstream>
#include <iostream>
#include <iterator>
#include <algorithm>
#include <boost/tuple/tuple.hpp>
#include <boost/iterator/zip_iterator.hpp>

typedef boost::tuples::tuple<unsigned,unsigned> DataPair;

namespace boost{
namespace tuples{

std::ostream & operator<<( std::ostream& stream , const DataPair& )
{
    return stream;
}

}
}

int main()
{
    std::vector<unsigned> data1( 10 , 1 );
    std::vector<unsigned> data2( 10 , 2 );

    std::ofstream outputFile( "Foo.txt" );
    std::ostream_iterator<DataPair> outputIterator( outputFile , "\n" ); 

    std::copy(
        boost::make_zip_iterator( boost::make_tuple( data1.begin() , data2.begin() ) ) ,
        boost::make_zip_iterator( boost::make_tuple( data1.end()   , data2.end()   ) ) ,
        outputIterator ); 
}

实际上,将operator <<放入std也有效,但不应该,因为它是未定义的行为

答案 1 :(得分:1)

DataPairOStream迭代器而不是。它适应 std::ostream到迭代器接口。

您需要定义

std::ostream & operator<< (std::ostream & os, const DataPair & dp)
{
    return os << boost::tuples::get<0>(dp) << boost::tuples::get<1>(dp);
}