473,396 Members | 2,033 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

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

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
6 5293
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
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
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
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
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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: Vespasian | last post by:
I create an templated Array class. My constructor declaration is as follows, template<class X> Array<X>::Array(int s); // Constructor I also have templated sorting function, template<class X>...
2
by: Martin Gernhard | last post by:
Hi, I'm trying to use expression templates to calculate values at compile time. Doing it with just one parameter is no problem: ///Begin Listing 1 #include <iostream> using namespace std; ...
5
by: amitmool | last post by:
hi, i have used the queue library file and try to use the template as template <class QueueItem> queue <QueueItem>::~queue() // line 25 { } template <class QueueItem> void...
2
by: parvtb | last post by:
I have the following code: #include <list> using namespace std; template <typename T> list<T>::iterator doStuff( list<T>::iterator myIter ) //--error here
3
by: Jeff | last post by:
Im compiling code on Fedora and I get the following error: 202: error: expected `;' before 'itr' this is in a .h file which has no .cpp file: template < typename Tcharl, typename Tcharr >...
5
by: nbransby | last post by:
Why does... class Foo { std::list<int> list; std::map<int, std::list<int>::iterator> map; }; ...compile, while this...
2
by: ndbecker2 | last post by:
On upgrading from gcc-4.1.2 to gcc-4.3, this (stripped down) code is now rejected: #include <vector> #include <iostream> template<typename T, template <typename Aclass CONT=std::vector>...
1
by: lovecreatesbea... | last post by:
In the following function `HardwareStatusDb()', If its arguments are declared as type of `string', I get: main.cpp:5: error: expected initializer before ‘int’. The error disappears when those...
2
by: prw8864 | last post by:
I can not see what is causing this error.... iterator has been defined properly, but the error seems to point to the interator type. Errors I get with g++ svector.c++ -o svector 2> ./err_txt...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.