чтение файла пар ключ-значение в std :: map

У меня есть проект Visual Studio 2008 C ++ 03, где я хотел бы прочитать файл пар ключ-значение в std :: map.
Для этого я создал istreambuf_pair_iterator как показано ниже:

typedef std::map< std::string, std::string > Properties;

class istreambuf_pair_iterator :
public boost::iterator_adaptor< istreambuf_pair_iterator,
std::pair< std::string, std::string >*,
boost::use_default,
boost::forward_traversal_tag >
{
public:
istreambuf_pair_iterator() : sb_( 0 ) { };
explicit istreambuf_pair_iterator( std::istream& is ) : sb_( is.rdbuf() ) { };

private:
void increment()
{
std::string line;
std::istream is( sb_ );
std::getline( is, line );

// TODO: parse the key=value to a std::pair
// where do I store the pair???
};

friend class boost::iterator_core_access;
std::streambuf* sb_;
};

Properties ReadProperties( const char* file )
{
std::ifstream f( file );
Properties p;
std::copy( istreambuf_pair_iterator( f ),
istreambuf_pair_iterator(),
std::inserter( p, p.end() ) );
return p;
}

Однажды у меня есть std::pair<> сделано из строки, прочитанной из файла, где я могу сохранить ее так, чтобы она могла быть вставлена std::inserter в к std::map?

4

Решение

Зачем использовать повышение для задач, которые могут быть достигнуты с помощью C ++ std?
Просто используйте istream_iterator с insert_iterator. Для этого вы должны определить в потоке пространства имен std << и операторы «>>» для вашего pair<string,string>, Что-то вроде этого:

namespace std {
// I am not happy that I had to put these stream operators in std namespace.
// I had to because otherwise std iterators cannot find them
// - you know this annoying C++ lookup rules...
// I know one solution is to create new type inter-operable with this pair...
// Just to lazy to do this - anyone knows workaround?
istream& operator >> (istream& is, pair<string, string>& ps)
{
return is >> ps.first >> ps.second;
}
ostream& operator << (ostream& os, const pair<const string, string>& ps)
{
return os << ps.first << "==>>" << ps.second;
}
}

И использование:

стандартный итератор вставки:

  std::map<std::string, std::string> mps;
std::insert_iterator< std::map<std::string, std::string> > mpsi(mps, mps.begin());

Итератор std istream:

  const std::istream_iterator<std::pair<std::string,std::string> > eos;
std::istream_iterator<std::pair<std::string,std::string> > its (is);

Чтение:

  std::copy(its, eos, mpsi);

Письмо (бонус):

  std::copy(mps.begin(), mps.end(),   std::ostream_iterator<std::pair<std::string,std::string> >(std::cout, "\n"));

Рабочий пример на Ideone

13

Другие решения

Других решений пока нет …