2011-12-15 1 views
0

これは大きなコンテキストから来ていますが、質問を簡略化するために多くのコードを削除しました。私が何かを残していると感じたら、私に知らせてください。ジェネリッククラス内のジェネリックコンテナにイテレータを取得する:HOW TO

は、テンプレートクラスを持つように定義としましょう:

#include <map> 
#include <vector> 
#include <string> 
#include <fstream> 
#include <iostream> 
#include <iterator> 
#include <algorithm> 
template <class key, class container, class container_type> 
class file_to_map 
{ 
public: 
    file_to_map() 
    { 
    m_file = ""; 
    } 

    file_to_map(std::string file) 
    { 
    m_file = file; 
    } 

    ~file_to_map() 
    { 
    } 

    std::map<key, container>& get_map() 
    { 
    return m_map; 
    } 

    void set_file(const std::string file) 
    { 
    m_file = file; 
    } 

    void insert_into_map(key insert, container_type value) 
    { 
    m_map[insert].insert(value); 
    } 

    friend std::ostream& operator<< (std::ostream &out, file_to_map<key, container, container_type> &obj) 
    { 
    typedef typename std::map<key, container>::const_iterator mapItr; 
    mapItr mbi = obj.m_map.begin(); 
    mapItr emi = obj.m_map.end(); 
    while (mbi != emi) { 
     out << " -- " << mbi->first << " -- " << std::endl; 
     container::iterator cbi; 
     ++mbi; 
    } 
    return out; 
    } 

    friend std::istream& operator>> (std::ifstream &in, file_to_map<key, container, container_type> &obj) 
    { 
    if (in.is_open()) 
     in.close(); 

    if (obj.m_file == "") 
     return in; 

    in.open(obj.m_file.c_str(), std::ios::in); 

    if (in.fail() || in.bad()) { 
     in.close(); 
     return in; 
    } 

    std::vector<key> tmp; 
    typedef std::istream_iterator<key> string_input; 
    copy(string_input(in), string_input(), back_inserter(tmp)); 
    typename std::vector<key>::iterator bvi = tmp.begin(); 
    typename std::vector<key>::iterator evi = tmp.end(); 
    while (bvi != evi) { 
     obj.m_map[*(bvi)] = container(); 
     ++bvi; 
    } 

    in.close(); 
    return in; 
    } 
    private: 
    std::map<key, container> m_map; 
    std::string m_file; 
}; 

と友人メソッド内「operator<<

あなたは1が行くだろうかマップのconentsとジェネリックcontainerを印刷したい

これをすることについて?ジェネリック containerの内容を反復処理するために、適切なイテレータを取得するにはどうすればよいですか。

:私は、次のコンパイラエラーを取得しています

friend std::ostream& operator<< (std::ostream &out, file_to_map<key, container, container_type> &obj) 
    { 
    typedef typename std::map<key, container>::const_iterator mapItr; 
    mapItr mbi = obj.m_map.begin(); 
    mapItr emi = obj.m_map.end(); 
    while (mbi != emi) { 
     out << " -- " << mbi->first << " -- " << std::endl; 
     typename container::const_iterator cbi = mbi->second.begin(); 
     typename container::const_iterator ebi = mbi->second.end(); 
     std::copy(cbi, mbi, std::ostream_iterator<container_type>(out, "\t\n")); 
     ++mbi; 
    } 
    return out; 
    } 

:付き

container::iterator cbi; 

コード更新

私はそれをしようとしています10

g++ -o file_to_map -Wall ./file_to_map.h ./main.cpp ./code_finder.cpp \ 
     -L/usr/local/boost_1_48_0/stage/lib -lboost_filesystem -lboost_system -I /usr/local/boost_1_48_0/ 
In file included from ./code_finder.h:4, 
       from ./code_finder.cpp:1: 
./file_to_map.h: In function ‘std::ostream& operator<<(std::ostream&, file_to_map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::set<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >&)’: 
./code_finder.cpp:36: instantiated from here 
./file_to_map.h:62: error: no matching function for call to ‘copy(std::_Rb_tree_const_iterator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >&, operator<<(std::ostream&, file_to_map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::set<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >&)::mapItr&, std::ostream_iterator<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, char, std::char_traits<char> >)’ 

私には何が欠けていますか?

答えて

6

使用typename

typename container::iterator cbi; 

それはクラステンプレートの型引数containerに依存するiteratorは、依存名ですので。興味深いことに、このようなoperator<<のように他の場所でtypenameを使用して補正した場合:あなたは、マップのconstのイテレータを使用してになるだろうコンテナオブジェクトを意味マップのconst_iteratorで作業しているので

typedef typename std::map<key, container>::const_iterator mapItr; 

constのオブジェクトになります。これは、コンテナにもconst_iteratorを使用する必要があることを意味します。これはマップの値であるためです。私はここにタイプミスを参照してください

typename container::const_iterator cbi = mbi->second.begin(); 
typename container::const_iterator ebi = mbi->second.end(); 
std::copy(cbi, mbi, std::ostream_iterator<container_type>(out, "\t\n")); 
      // ^^^ typo 

std::copyへの第2引数はebiする必要があり、あなたの編集に

typename container::const_iterator cbi; //use this instead! 

返信:だから私は、あなたがこれを使用する必要があると思いますないmbi。だから私は通常、cbiebiの代わりに、beginendのような変数の名前を付けます。

+0

このコメントはかなり助けになりましたが、私はまだいくつかの小さな問題を抱えています。私は上記の投稿に追加しました。 –

+0

@MatthewHoggan:あなたの編集にも返信しました。あなたのコードにはタイプミスがあります。 – Nawaz

+0

これは、毎日のビルドの直前に急いで修正するためのものです。彼が助けてくれてありがとう。 –