Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Dependent Template Issue? g++ gives the following ==> error: expected primary-expression before "int"

Reply
Thread Tools

Dependent Template Issue? g++ gives the following ==> error: expected primary-expression before "int"

 
 
Lawrence Spector
Guest
Posts: n/a
 
      07-12-2007
I ran into a problem using g++. Visual Studio 2005 never complained
about this, but with g++ I ran into this error. I can't figure out if
I've done something wrong or if this is a compiler bug. Here's a very
simple example which should illustrate what I'm doing.

#include <iostream>

template <class T>
class TestBase
{
public:
TestBase() {}

int testMethod()
{
return T::callMethod<int>(); // ERROR?
}
};

class Derived : public TestBase<Derived>
{
public:
Derived() : TestBase<Derived>() {}


template <class T>
T callMethod()
{
return T();
}
};

int main()
{
Derived derived;

int x = derived.callMethod<int>();
int y = derived.testMethod(); // CALLED FROM HERE

return 0;
}


Results in the following:

$ g++ -c GccTemplateCompile.cpp
GccTemplateCompile.cpp: In member function `int
TestBase<T>::testMethod()':
GccTemplateCompile.cpp:12: error: expected primary-expression before
"int"
GccTemplateCompile.cpp:12: error: expected `;' before "int"
GccTemplateCompile.cpp:12: error: expected primary-expression before
"int"
GccTemplateCompile.cpp:12: error: expected `;' before "int"

Does anyone have any idea what's going on?

Thanks in advance,

Lawrence

 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      07-12-2007
Lawrence Spector wrote:
> I ran into a problem using g++. Visual Studio 2005 never complained
> about this, but with g++ I ran into this error. I can't figure out if
> I've done something wrong or if this is a compiler bug. Here's a very
> simple example which should illustrate what I'm doing.
>
> #include <iostream>
>
> template <class T>
> class TestBase
> {
> public:
> TestBase() {}
>
> int testMethod()
> {
> return T::callMethod<int>(); // ERROR?


Add the keyword template:

return T::template callMethod<int>();

Also, it is most likely that it's not going to work since
even if 'callMethod' is a member of 'T', you would need
an instance of 'T' to call non-static member function. If
you hope to use 'this' here, it shouldn't work because
there is no convestion from 'this' (which is of the type
'TestBase<T>' to 'T').

> }
> };
>
> class Derived : public TestBase<Derived>
> {
> public:
> Derived() : TestBase<Derived>() {}
>
>
> template <class T>
> T callMethod()
> {
> return T();
> }
> };
>
> int main()
> {
> Derived derived;
>
> int x = derived.callMethod<int>();
> int y = derived.testMethod(); // CALLED FROM HERE
>
> return 0;
> }
>
>
> Results in the following:
>
> $ g++ -c GccTemplateCompile.cpp
> GccTemplateCompile.cpp: In member function `int
> TestBase<T>::testMethod()':
> GccTemplateCompile.cpp:12: error: expected primary-expression before
> "int"
> GccTemplateCompile.cpp:12: error: expected `;' before "int"
> GccTemplateCompile.cpp:12: error: expected primary-expression before
> "int"
> GccTemplateCompile.cpp:12: error: expected `;' before "int"
>
> Does anyone have any idea what's going on?


The compiler does not know that 'callMethod' is a template member.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


 
Reply With Quote
 
 
 
 
Alf P. Steinbach
Guest
Posts: n/a
 
      07-12-2007
* Lawrence Spector:
> I ran into a problem using g++. Visual Studio 2005 never complained
> about this, but with g++ I ran into this error. I can't figure out if
> I've done something wrong or if this is a compiler bug. Here's a very
> simple example which should illustrate what I'm doing.
>
> #include <iostream>
>
> template <class T>
> class TestBase
> {
> public:
> TestBase() {}
>
> int testMethod()
> {
> return T::callMethod<int>(); // ERROR?


Yes, unless "callMethod" is a static member of "T".


--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
 
Reply With Quote
 
Robert Bauck Hamar
Guest
Posts: n/a
 
      07-12-2007
Lawrence Spector wrote:

> I ran into a problem using g++. Visual Studio 2005 never complained
> about this, but with g++ I ran into this error. I can't figure out if
> I've done something wrong or if this is a compiler bug. Here's a very
> simple example which should illustrate what I'm doing.
>
> #include <iostream>
>
> template <class T>
> class TestBase
> {
> public:
> TestBase() {}
>
> int testMethod()
> {
> return T::callMethod<int>(); // ERROR?


return T::template callMethod<int>();

would be the correct syntax. The template keyword says that the following
name is a template, and thus that a following < is not the less than
operator. This is needed because the compiler at this time cannot know what
the members of T is.

But as callMethod is a nonstatic member function, you cannot do this. If you
had a T object, you could do:

T t;
return t.template callMethod<int>();

> }
> };
>
> class Derived : public TestBase<Derived>
> {
> public:
> Derived() : TestBase<Derived>() {}
>
>
> template <class T>
> T callMethod()
> {
> return T();
> }
> };
>
> int main()
> {
> Derived derived;
>
> int x = derived.callMethod<int>();


Here, you shouldn't use the template keyword, because the compiler already
know what a Derived object contains.

> int y = derived.testMethod(); // CALLED FROM HERE
>
> return 0;
> }
>
>
> Results in the following:
>
> $ g++ -c GccTemplateCompile.cpp
> GccTemplateCompile.cpp: In member function `int
> TestBase<T>::testMethod()':
> GccTemplateCompile.cpp:12: error: expected primary-expression before
> "int"
> GccTemplateCompile.cpp:12: error: expected `;' before "int"
> GccTemplateCompile.cpp:12: error: expected primary-expression before
> "int"
> GccTemplateCompile.cpp:12: error: expected `;' before "int"
>
> Does anyone have any idea what's going on?


You have to tell the compiler that you are using a template, because at the
time, the compiler cannot tell if T::callMethod is a template.

If you look at the error message, it makes sense if you know that the
compiler thinks it is about to parse a less than expression: It has found
T::callMethod, and the standard says that it should assume it is an object,
and a < operator to use with this object as left hand side.

--
rbh
 
Reply With Quote
 
Lawrence Spector
Guest
Posts: n/a
 
      07-12-2007
My response doesn't look like it went through, so let me try again.

I added the template so it now looks like this:

template <class T>
class TestBase
{
public:
TestBase() {}

int testMethod()
{
return T::template callMethod<int>(); // ERROR?
}

};

As mentioned, this results in a different problem, shown below:

$ g++ -c GccTemplateCompile.cpp
GccTemplateCompile.cpp: In member function `int
TestBase<T>::testMethod() [with
T = Derived]':
GccTemplateCompile.cpp:33: instantiated from here
GccTemplateCompile.cpp:11: error: cannot call member function `T
Derived::callMe
thod() [with T = int]' without object


Now, the issue you guys is say is that I don't have an instance. And
yet, I should, because that class is a derivative of this one. Does
the curiously recurring template pattern not work in g++?

Regardless, what's the proper way to do this in C++?

Thanks again,

Lawrence

 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      07-12-2007
Lawrence Spector wrote:
> My response doesn't look like it went through, so let me try again.
>
> I added the template so it now looks like this:
>
> template <class T>
> class TestBase
> {
> public:
> TestBase() {}
>
> int testMethod()
> {
> return T::template callMethod<int>(); // ERROR?
> }
>
> };
>
> As mentioned, this results in a different problem, shown below:
>
> $ g++ -c GccTemplateCompile.cpp
> GccTemplateCompile.cpp: In member function `int
> TestBase<T>::testMethod() [with
> T = Derived]':
> GccTemplateCompile.cpp:33: instantiated from here
> GccTemplateCompile.cpp:11: error: cannot call member function `T
> Derived::callMe
> thod() [with T = int]' without object
>
>
> Now, the issue you guys is say is that I don't have an instance. And
> yet, I should, because that class is a derivative of this one.


So what? In a base class member, 'this' is not implicitly convertible
to any derived class. If you insist (and your 'TestBase' knows that
'T' derives from it), do

static_cast<T*>(this)->template callMethod<int>();

> Does
> the curiously recurring template pattern not work in g++?
>
> Regardless, what's the proper way to do this in C++?


V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


 
Reply With Quote
 
Alf P. Steinbach
Guest
Posts: n/a
 
      07-12-2007
* Lawrence Spector:
> My response doesn't look like it went through, so let me try again.
>
> I added the template so it now looks like this:
>
> template <class T>
> class TestBase
> {
> public:
> TestBase() {}
>
> int testMethod()
> {
> return T::template callMethod<int>(); // ERROR?


Yes, unless "callMethod" is a static member of "T".

Hey, I already told you that.

Why don't you read the responses you get?


> }
>
> };
>
> As mentioned, this results in a different problem, shown below:
>
> $ g++ -c GccTemplateCompile.cpp
> GccTemplateCompile.cpp: In member function `int
> TestBase<T>::testMethod() [with
> T = Derived]':
> GccTemplateCompile.cpp:33: instantiated from here
> GccTemplateCompile.cpp:11: error: cannot call member function `T
> Derived::callMe
> thod() [with T = int]' without object
>
>
> Now, the issue you guys is say is that I don't have an instance. And
> yet, I should, because that class is a derivative of this one. Does
> the curiously recurring template pattern not work in g++?
>
> Regardless, what's the proper way to do this in C++?


Depends what you're trying to achieve. You can, for example,

* Make callMethod a static member.
* Downcast the "this" pointer and call through that.
* Use a virtual function and no templates.
* Pass a function pointer.
* Even a switch construction might be appropriate.

All depending on what exactly you're trying to achieve.

Context does matter, and you haven't provided any hint, not a single
clue, about what the gnargle-gnargle you're trying to achieve.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
 
Reply With Quote
 
Lawrence Spector
Guest
Posts: n/a
 
      07-12-2007
On Jul 12, 4:16 pm, "Victor Bazarov" <(E-Mail Removed)> wrote:
> Lawrence Spector wrote:
> > My response doesn't look like it went through, so let me try again.

>
> > I added the template so it now looks like this:

>
> > template <class T>
> > class TestBase
> > {
> > public:
> > TestBase() {}

>
> > int testMethod()
> > {
> > return T::template callMethod<int>(); // ERROR?
> > }

>
> > };

>
> > As mentioned, this results in a different problem, shown below:

>
> > $ g++ -c GccTemplateCompile.cpp
> > GccTemplateCompile.cpp: In member function `int
> > TestBase<T>::testMethod() [with
> > T = Derived]':
> > GccTemplateCompile.cpp:33: instantiated from here
> > GccTemplateCompile.cpp:11: error: cannot call member function `T
> > Derived::callMe
> > thod() [with T = int]' without object

>
> > Now, the issue you guys is say is that I don't have an instance. And
> > yet, I should, because that class is a derivative of this one.

>
> So what? In a base class member, 'this' is not implicitly convertible
> to any derived class. If you insist (and your 'TestBase' knows that
> 'T' derives from it), do
>
> static_cast<T*>(this)->template callMethod<int>();
>
> > Does
> > the curiously recurring template pattern not work in g++?

>
> > Regardless, what's the proper way to do this in C++?

>
> V


Gotcha. I'm past the problem. Thanks for the help.

On Jul 12, 4:17 pm, "Alf P. Steinbach" <(E-Mail Removed)> wrote:
> Yes, unless "callMethod" is a static member of "T".
>
> Hey, I already told you that.
>
> Why don't you read the responses you get?


Just to clarify before any misunderstandings, I read the suggestions
and then tried them for myself to try to enhance my understanding of
the issue. My understanding is now enhanced. Thanks.

Thanks for the assistance, everyone. I very much appreciate it.

 
Reply With Quote
 
Lawrence Spector
Guest
Posts: n/a
 
      07-12-2007
On Jul 12, 4:16 pm, "Victor Bazarov" <(E-Mail Removed)> wrote:
> Lawrence Spector wrote:
> > My response doesn't look like it went through, so let me try again.

>
> > I added the template so it now looks like this:

>
> > template <class T>
> > class TestBase
> > {
> > public:
> > TestBase() {}

>
> > int testMethod()
> > {
> > return T::template callMethod<int>(); // ERROR?
> > }

>
> > };

>
> > As mentioned, this results in a different problem, shown below:

>
> > $ g++ -c GccTemplateCompile.cpp
> > GccTemplateCompile.cpp: In member function `int
> > TestBase<T>::testMethod() [with
> > T = Derived]':
> > GccTemplateCompile.cpp:33: instantiated from here
> > GccTemplateCompile.cpp:11: error: cannot call member function `T
> > Derived::callMe
> > thod() [with T = int]' without object

>
> > Now, the issue you guys is say is that I don't have an instance. And
> > yet, I should, because that class is a derivative of this one.

>
> So what? In a base class member, 'this' is not implicitly convertible
> to any derived class. If you insist (and your 'TestBase' knows that
> 'T' derives from it), do
>
> static_cast<T*>(this)->template callMethod<int>();
>
> > Does
> > the curiously recurring template pattern not work in g++?

>
> > Regardless, what's the proper way to do this in C++?

>
> V


Gotcha. I'm past the problem.

Thanks for the assistance, everyone.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
The following code gives two "Identifier expected" errors AAaron123 ASP .Net 0 03-12-2009 02:17 PM
non-dependent vs. dependent template names puzzlecracker C++ 1 08-07-2008 07:42 AM
error: expected `;' before 'itr' template compile error? Solaris vsLinux Jeff C++ 3 03-11-2008 08:29 PM
hiding non template dependent implementation in a template class er C++ 1 10-16-2007 01:15 AM
template template arguments: expected a class template, got `Component<T1, T2, T3> gary.bernstein@gmail.com C++ 1 06-08-2007 07:10 AM



Advertisments