By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
434,916 Members | 1,286 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 434,916 IT Pros & Developers. It's quick & easy.

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

P: n/a
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

Jul 12 '07 #1
Share this Question
Share on Google+
6 Replies


P: n/a
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
Jul 12 '07 #2

P: n/a
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
Jul 12 '07 #3

P: n/a
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

Jul 12 '07 #4

P: n/a
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
Jul 12 '07 #5

P: n/a
On Jul 12, 4:16 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
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" <a...@start.nowrote:
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.

Jul 12 '07 #6

P: n/a
On Jul 12, 4:16 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
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.

Jul 12 '07 #7

This discussion thread is closed

Replies have been disabled for this discussion.