3

That might be a silly question, but I'm staring at this code for a while and can't think of what's wrong. On compiling:

#include <string>
#include <map>

template <typename T>
struct my_string_map {
    typedef std::map<std::string, T> type;
};
template <typename T> bool add_to_string_map(my_string_map<T>::type map,
        std::string str, T x) {
    if (map.find(str) != map.end()) 
        return false;
    map[str] = x;
    return true;
}

I get:

foo.cpp:8: error: template declaration of ‘bool add_to_string_map’
foo.cpp:8: error: expected ‘)’ before ‘map’
foo.cpp:8: error: expected primary-expression before ‘str’
foo.cpp:8: error: expected primary-expression before ‘x’

(Definition of my_string_map class was taken from another thread of this forum)

When i specialize what template type I'm using, like in

bool add_to_string_int_map(my_string_map<int>::type map,
        std::string str, int x) {
    if (map.find(str) != map.end()) 
        return false;
    map[str] = x;
    return true;
}

everything works fine. Why it's not working and/or how to get it working?

Thanks in advance for your help

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
karoluch
  • 31
  • 1
  • 4

3 Answers3

7

Try putting typename before the my_string_map<T>::type argument.

For more info, see: https://isocpp.org/wiki/faq/templates#nondependent-name-lookup-types.

Gunther Struyf
  • 11,158
  • 2
  • 34
  • 58
Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
4

my_string_map<T>::type is a dependent name, as it depends on the template parameter T. For dependent names, you need to use typename:

template <typename T>
bool add_to_string_map(typename my_string_map<T>::type map, std::string str, T x) {
    ...
}
hammar
  • 138,522
  • 17
  • 304
  • 385
1

The compiler will not be able to deduce T. It seems obvious to a human but from the point of view of the compiler, this kind of deduction is impossible. The specialization works because you're no longer asking the compiler to deduce T.

Puppy
  • 144,682
  • 38
  • 256
  • 465