template class error

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream>
#include <string>
#include <map>
#include <vector>
#include <sstream>
#include <iomanip>

template <class KEY, class VALUE>
class Dict{
    public:
        std::map<KEY, VALUE> dictionary;
        
        void update(KEY k, VALUE v){
            dictionary[k] = v;
        }
        
        std::vector<KEY> keys(){
            std::vector<KEY> v;
            for(std::map<KEY, VALUE>::const_iterator it = dictionary.begin();
            it != dictionary.end(); ++it){
                v.push_back(it->first);
            }
            return v;
        }
        
        std::vector<VALUE> values(){
            std::vector<VALUE> v;
            for(std::map<KEY, VALUE>::const_iterator it = dictionary.begin();
            it != dictionary.end(); ++it){
                v.push_back(it->second);
            }
            return v;
        }
};

int main(){
    Dict<std::string, std::string> d;
    d.update("key", "value");
    d.update("key2", "value2");
    
    for (auto i:d.keys())
        std::cout << i << std::endl;
        
    for (auto i:d.values())
        std::cout << i << std::endl;
}

compile error:
1
2
3
test.cpp: In member function ‘std::vector<KEY> Dict<KEY, VALUE>::keys()’:
test.cpp:19:17: error: need ‘typename’ before ‘std::map<KEY, VALUE>::const_iterator’ because ‘std::map<KEY, VALUE>’ is a dependent scope
             for(std::map<KEY, VALUE>::const_iterator it = dictionary.begin();

I am not really sure what this means?

Though it compiles fine if i was to remove the KEY and VALUE for the std::map loops in class members and input them directly, but that loses the point of doing it in the first place.

EDIT:
1
2
for(class std::map<KEY, VALUE>::const_iterator it = dictionary.begin();
            it != dictionary.end(); ++it){

ok going off of the error and googling, i know now that class or typename needs to preceed the std::map, but now my question is why ?
Last edited on
When the template definition is seen, the compiler needs to know, for each name, whether it names an object, a type, a namespace, a template, etc. Otherwise it can't parse C++ source code.

When you're referring to a name that is nested inside a class template, it cannot just look up into that primary template definition (where const_iterator names a type) :you might decide to write a full specialization of std::map for some specific key and value and make const_iterator a variable in there. So you have to promise that it names a type, with the keyword typename.

See also http://en.cppreference.com/w/cpp/language/dependent_name for more details.
Last edited on
well...that does make sense. I had to reread it a few times, but got it. thanks for the links
Topic archived. No new replies allowed.