56

This code compiles and works as expected (it throws at runtime, but never mind):

#include <iostream>
#include <boost/property_tree/ptree.hpp>

void foo(boost::property_tree::ptree &pt) 
{
    std::cout << pt.get<std::string>("path"); // <---
}

int main()
{
    boost::property_tree::ptree pt;
    foo(pt);
    return 0;
}

But as soon as I add templates and change the foo prototype into

template<class ptree>
void foo(ptree &pt)

I get an error in GCC:

test_ptree.cpp: In function ‘void foo(ptree&)’:
test_ptree.cpp:7: error: expected primary-expression before ‘>’ token

but no errors with MSVC++! The error is in the marked line <---. And again, if I change the problem line into

--- std::cout << pt.get<std::string>("path"); // <---
+++ std::cout << pt.get("path", "default value");

the error disappears (the problem is in explicit <std::string>).

Boost.PropertyTree requires Boost >= 1.41. Please help me to understand and fix this error.


See Templates: template function not playing well with class’s template member function — a similar popular question containing other good answers and explanations.

Community
  • 1
  • 1
Andrew T
  • 5,549
  • 7
  • 43
  • 55
  • 1
    Related: http://stackoverflow.com/questions/1682844/templates-template-function-not-playing-well-with-classs-template-member-functi/1682885 (Duplicate?) – GManNickG Aug 17 '10 at 18:37
  • 1
    Yes, it's a duplicate. Thank you for your help! – Andrew T Aug 17 '10 at 18:45
  • Does this answer your question? [Templates: template function not playing well with class's template member function](https://stackoverflow.com/questions/1682844/templates-template-function-not-playing-well-with-classs-template-member-funct) – hellow Mar 09 '20 at 14:25
  • Sorry to excavate this, but if you say that this is a duplicate, it should be marked as such IMHO :) – hellow Mar 09 '20 at 14:26

1 Answers1

90

You need to do:

std::cout << pt.template get<std::string>("path");

Use template in the same situation as typename, except for template members instead of types.

(That is, since pt::get is a template member dependent on a template parameter, you need to tell the compiler it's a template.)

GManNickG
  • 494,350
  • 52
  • 494
  • 543
  • 2
    Nice. Do you have a specific resource you use for template usage? I ask out of curiosity. None of my books seemed to address this issue. – Chance Aug 24 '11 at 16:52
  • @Chance: I don't, sadly, though you might find one off [this list](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list), namely *C++ Templates, The Complete Guide*. – GManNickG Aug 24 '11 at 18:18
  • 3
    Why do you need to tell the compiler it's a template? Shouldn't the compiler be able to figure that out by itself? – HelloGoodbye Oct 13 '15 at 13:17
  • 4
    @HelloGoodbye: I don't remember if it's theoretically possible in C++ for the compiler to always deduce it correctly, probably not. The problem is that without `template`, it could be parsed as `(pt.get) < std::string > ("path");`, that is comparisons. In this case, comparisons for type names isn't possible so it could figure out, but in general how would you parse `pt.val < 5 > (10)`? Adding `template` tells the compiler directly "this is a function call". – GManNickG Oct 13 '15 at 22:44
  • 1
    Ah, okay, so it is the old incompatibility problem with comparison operators and template notation again... :P Well, that makes sense. I guess the D programming language has the upper hand here with its `(...)` template syntax instead of C++' `<...>` syntax :) – HelloGoodbye Oct 14 '15 at 11:27