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 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
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
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
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
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.
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. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
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>...
|
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;
...
|
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...
|
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
|
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 >...
|
by: nbransby |
last post by:
Why does...
class Foo
{
std::list<int> list;
std::map<int, std::list<int>::iterator> map;
};
...compile, while this...
|
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>...
|
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...
|
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...
|
by: Charles Arthur |
last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
|
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
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
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...
|
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,...
|
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...
|
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,...
|
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...
|
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...
| |