I am having an issue with templates.
It is strange because the very very same line of code compiles well if it is inside main, but not if it is inside a function.
The error message that I get is the following:
trycmp.cpp: In function 'void freefunct(Component<T>*)':
trycmp.cpp:30: error: missing template arguments before '>' token
trycmp.cpp:30: error: expected primary-expression before ')' token
Below I report a minimal version of the code I am working on, which reproduces the same problem. I would be grateful if anyone could help me in finding out what is going on.
#include<set>
template<class T>
class Maximal
{
public:
typedef std::set<T> EdgSet;
typedeftypename EdgSet::reverse_iterator EdgIter;
static EdgIter edgBegin(const EdgSet& S) {return S.rbegin();}
};
template<class T>
class Component
{
public:
std::set<T> outEdg;
template<template<class U> class OP> inlinetypename OP<T>::EdgIter outBegin() const {return OP<T>::edgBegin(this->outEdg);}
Component() {}
~Component() {}
};
template<class T>
void freefunct(Component<T>* conn)
{
conn->outBegin<Maximal>();
return;
}
int main()
{
Component<int>* conn = new Component<int>;
conn->outBegin<Maximal>();
freefunct<int>(conn); //This is where I get the issue. If I comment it out, as well as the definition of freefunct, it compiles properly
return 0;
}
I am still unclear about one thing. From the liks you gave me I see that without the disambiguator the angle bracket that opens the template is interpreted as a less operator.'
However, why don't I get the same error when thesame call is made from main() instead of from. Freefunct()?
in main, the type of conn and all its members is known. In freefunct it isn't known - the compiler may yet encounter a specialization of Component which redefines outBegin as a member variable or as a member type (or perhaps doesn't define it at all).
@ JLBorges: I saw your reply, and I don't know why you deleted it. Let me know via PM if you want me to edit it out.
JLBorges wrote:
> why don't I get the same error when thesame call is made from main()
In a template that we write, there are two kinds of names that could be used - dependant names and non-dependant names. A dependant name is a name that depends on a template parameter (what a dependant name refers to could be something different for each different instantiation of the template); a non-dependant name has the same meaning irrespective of what the template parameters are.
As a consequence, C++ templates are subject to "two-phase name lookup". When a template is initially parsed (phase one, before any template instantiation has actually taken place) the parser needs to be told if a dependant name is the name of a template.
In freefunct<T>(), Component<T>::outBegin is a dependant name. It depends on what T is
(Component<T> might have been specialized for some type).
In main(), there are no dependant names, there is no two-phase name lookup, there is no ambiguity about what Component<int>::outBegin is.
I deleted it because after I posted it, I saw that Cubbi had already answered the question. I was essentially repeating, in slightly different words, what had been said earlier.
Keep it, if you feel that it is useful.
EDIT: Also hadn't seen your (Catfish666) post till a few seconds ago.