One thing I love about C++ is that no matter how long you’ve been doing it, you will never cease running up against bizarre corner cases and general language weirdness.

Imagine the following simple program:

#include <boost/property_tree/json_parser.hpp>
#include <sstream>
#include <iostream>
#include <string>

int main()
{
    std::stringstream ss;
    ss << "{ \"Animals\": [ "
                "{\"name\": \"bunnies\"},"
                "{\"name\": \"foxes\"}]}";

    boost::property_tree::ptree pt;
    read_json(ss, pt);

    for (const auto &v : pt.get_child("Animals"))
        std::cout << v.second.get<std::string>("name") << std::endl;
}

Take note that a type of v here is actually std::pair<const std::basic_string<char>, boost::property_tree::basic_ptree<std::basic_string<char>, std::basic_string<char>, std::less<std::basic_string<char>>>> (thank goodness for the auto keyword) which is, of course, a instantiation of a templated class.

Now I can see myself needing to call v.second.get<std::string>() several times here, maybe with different nodes besides name. So why not make a helper function.

template <typename T>
std::string get_string(const T &pt, const std::string &node)
{
    return pt.second.get<std::string>(node);
}

Since pt was that long crazy type we had before we’ll just use a template for the function parameter and let the compiler do the work. Ok, but does it compile?

$ g++ -std=c++11 test.cpp
test.cpp:11:37: error: expected primary-expression before ‘>’ token
     return pt.second.get<std::string>(node);

Wait, what? Unfortunately I’ve been doing this long enough to find one or two compiler bugs of my own. Nothing is certain in this world, not even compilers; Lets try a different one.

$ clang++ -std=c++11 test.cpp
test.cpp:9:22: error: use 'template' keyword to treat 'get' as a dependent template name

Okay, so this one is telling us how to fix it but not what’s wrong. Indeed, following the advice will result in successful compilation.

template <typename T>
std::string get_string(const T &pt, const std::string &node)
{
    return pt.second.template get<std::string>(node);
}

The question is why?

Put simply a dependant template name is a name whose definition depends on template parameters i.e. std::string in our get<std::string> example above. Now Clang is telling us to use some special syntax to to treat get as a dependant template name; so clearly, that’s not what the compiler thinks it is when we try to compile the original code. Indeed this is confirmed by the current Working Draft of the standard. From Section 14.2/4.

When the name of a member template specialization appears after . or -> in a postfix-expression or after a nested-name-specifier in a qualified-id, and the object expression of the postfix-expression is type-dependent or the nested-name-specifier in the qualified-id refers to a dependent type, but the name is not a member of the current instantiation (14.6.2.1), the member template name must be prefixed by the keyword template. Otherwise the name is assumed to name a non-template.

So if we don’t add the template keyword it is assumed to name a non-template. The only other use for < and > in C++ are as comparison operators. When we think about it like that, GCC’s error message makes much more sense now.