2012-05-03 3 views
0

Мне нужна помощь в определении специальности map, я не могу получить специальную карту :: iterator для компиляции вправо.Как определить итератор в классе std :: map

Как мне определить этот итератор для вызова find()?

Код:

// My case-insensitive-less functor, which has historically worked fine for me: 
struct ci_less : std::binary_function<std::string, std::string, bool> 
{ 
    // case-independent (ci) compare_less binary function 
    struct nocase_compare : public std::binary_function<unsigned char,unsigned char,bool> 
    { 
    bool operator() (const unsigned char& c1, const unsigned char& c2) const { 
     return tolower (c1) < tolower (c2); 
    } 
    }; 
    bool operator() (const std::string & s1, const std::string & s2) const { 
    return std::lexicographical_compare (s1.begin(), s1.end(), 
             s2.begin(), s2.end(), 
             nocase_compare()); // comparison 
    } 
}; 

//My offending code: 
template <class T> 
class CaseInsensitiveMap : public map<string, T, ci_less> 
{ 
public: 
// This one actually works, but it requires two "find()" calls. 
// I can't ethically call find twice. 
    const T* lookup(const T& key) const { 
    if (find(key) == map<string, T, ci_less>::end()) return 0; 
    else            return &find(key)->first; 
    } 
// This one complains with errors shown below. 
    T* lookup(const T& key) { 
    CaseInsensitiveMap<T>::iterator itr = find(key); 
    if (itr == map<string, T, ci_less>::end()) return 0; 
    else    return itr->second; 
    } 
}; 

Ошибки:

In member function 'T* CaseInsensitiveMap<T>::lookup(const T&)' :
    error: expected ';' before 'itr'
    error: 'itr' was not declared in this scope

+1

Я не думаю, что 'std :: map' предназначалось для унаследованного. – chris

+2

В будущем, пожалуйста, разместите свой код и ошибки в строке, а не ссылайтесь на внешний сайт. – ildjarn

ответ

4

typename Добавьте ключевое слово типа вашей переменной:

typename CaseInsensitiveMap<T>::iterator itr = find(key); 

Во всяком случае, вы не должны наследовать STL контейнеры. Читайте о том, почему вы не должны это делать here.

Edit: Так как все вы реализуете случай insenstitive карта, вы можете реализовать это таким образом, не наследуя std::map, просто указав свой собственный объект сравнения:

#include <iostream> 
#include <map> 
#include <string> 

using namespace std; 

struct nocase_compare { 
    bool operator() (const unsigned char& c1, const unsigned char& c2) const { 
     return tolower (c1) < tolower (c2); 
    } 
}; 

struct map_comparer { 
    bool operator() (const std::string & s1, const std::string & s2) const { 
    return std::lexicographical_compare (s1.begin(), s1.end(), 
             s2.begin(), s2.end(), 
             nocase_compare()); // comparison 
    } 
}; 

template<class T> 
struct CaseInsensitiveMap { 
    typedef std::map<std::string, T, map_comparer> type; 
}; 

int main() { 
    CaseInsensitiveMap<int>::type my_map; 
    my_map["foo"] = 12; 
    std::cout << my_map["FoO"] << "\n"; 
    my_map["FOO"] = 100; 
    std::cout << my_map["fOo"] << "\n"; 
} 

Воспроизводит:

12 
100 
0

typename CaseInsensitiveMap :: iterator itr = find (key);

по строке # 31