使用 Boost zip_iterator 将两个向量写入 CSV 文件
Using Boost zip_iterator to write two vectors to CSV file
我有两个向量要以 CSV 格式写入文件。我可以使用 for 循环 "by hand" 来做到这一点,但我第一次尝试使用 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;
~~~~~~~~~~~^~~~~~~~~~
DataPairOStream
是一个 迭代器 而不是 流 。它适应一个std::ostream
迭代器接口。
你需要定义
std::ostream & operator<< (std::ostream & os, const DataPair & dp)
{
return os << boost::tuples::get<0>(dp) << boost::tuples::get<1>(dp);
}
这个应该很好用。现在 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
中也有效,但 不应 完成,因为它是 未定义的行为.
我有两个向量要以 CSV 格式写入文件。我可以使用 for 循环 "by hand" 来做到这一点,但我第一次尝试使用 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;
~~~~~~~~~~~^~~~~~~~~~
DataPairOStream
是一个 迭代器 而不是 流 。它适应一个std::ostream
迭代器接口。
你需要定义
std::ostream & operator<< (std::ostream & os, const DataPair & dp)
{
return os << boost::tuples::get<0>(dp) << boost::tuples::get<1>(dp);
}
这个应该很好用。现在 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
中也有效,但 不应 完成,因为它是 未定义的行为.