Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

"expected primary-expression before '>'" error?

792 views
Skip to first unread message

john.wil...@yahoo.com

unread,
Apr 18, 2008, 7:19:51 PM4/18/08
to
The following code gives an "expected primary-expression before '>'"
error when compiled with gcc, Dev-C++ version 4.9.9.2. There is no
such error with MSVC 2005 or 2008. I would be grateful to know if it a
gcc bug, or alternatively what is wrong with the code.

template< typename G >
struct Test
{
template< typename T > T f() const;
};

template< typename G, typename T >
void g()
{
Test< G > t;

t.f< T >(); // error reported for this line
}

void test()
{
g< float, int >();
}

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Matthew Collett

unread,
Apr 19, 2008, 3:39:24 AM4/19/08
to
In article
<6aceaefc-b74b-4632...@e67g2000hsa.googlegroups.com>,
john.wil...@yahoo.com wrote:

> The following code gives an "expected primary-expression before '>'"
> error when compiled with gcc, Dev-C++ version 4.9.9.2. There is no
> such error with MSVC 2005 or 2008. I would be grateful to know if it a
> gcc bug, or alternatively what is wrong with the code.
>
> template< typename G >
> struct Test
> {
> template< typename T > T f() const;
> };
>
> template< typename G, typename T >
> void g()
> {
> Test< G > t;
>
> t.f< T >(); // error reported for this line
> }

You need

t.template f< T >();

The type of 't' depends on the template parameter 'G'. There is no
guarantee that in every specialisation of the template 'Test' the member
'f' will be a template. If the compiler is not told explicitly that 'f'
is in fact a template, it should assume that it is _not_, and parse '<'
as less-than rather than opening a template parameter.

Best wishes,
Matthew Collett

--
http://homepages.ihug.co.nz/~m_collett

aceh...@gmail.com

unread,
Apr 19, 2008, 3:39:17 AM4/19/08
to
On Apr 18, 4:19 pm, john.wilkinso...@yahoo.com wrote:
> The following code gives an "expected primary-expression before '>'"
> error when compiled with gcc, Dev-C++ version 4.9.9.2. There is no
> such error with MSVC 2005 or 2008. I would be grateful to know if it a
> gcc bug, or alternatively what is wrong with the code.

gcc conforms to the standard and VC++ is behaving smarter than what
the standard requires.

> template< typename G >
> struct Test
> {
> template< typename T > T f() const;
>
> };
>
> template< typename G, typename T >
> void g()
> {
> Test< G > t;
>
> t.f< T >(); // error reported for this line
> }

Above, f depends on a template parameter. It can be a member variable,
an enum value, a member function, etc. of Test<G>. Unless told, the
compiler cannot know that f is a template itself.

So it parses the < character as "less than" and gets confused later
on.

You must tell the compiler that f is a template so that it parses < as
the opening bracket of a template parameter list. Sorry for the busy
syntax: :)

t.template f< T >();

Ali

Thomas Maeder

unread,
Apr 19, 2008, 4:01:55 AM4/19/08
to
john.wil...@yahoo.com writes:

> The following code gives an "expected primary-expression before '>'"
> error when compiled with gcc, Dev-C++ version 4.9.9.2. There is no
> such error with MSVC 2005 or 2008. I would be grateful to know if it
> a gcc bug, or alternatively what is wrong with the code.

The code is wrong.


> template< typename G >
> struct Test
> {
> template< typename T > T f() const;
> };
>
> template< typename G, typename T >
> void g()
> {
> Test< G > t;
> t.f< T >(); // error reported for this line

Since the name t is dependant, it's impossible for the compiler to
determine what the name t.f names. But the compiler needs this
information to determine whether < is the start of a template
parameter list or the less than operator.

The code therefore has to disambiguate the situation. The rule is that
unless the compiler is told otherwise, it has to assume that t.f does
not name a template. To tell the compiler otherwise, do

t.template f< T >();

0 new messages