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

compiler specific: gcc and templates

P: n/a
This code below compiles fine with VS.2005 but with gcc 3.4.2 not.
------------------
template<class T>
static void Wastage1D::clever_erase(vector<T> &v, vector<typename
vector<T>::iterator> &its, vector<T> &vo)
{ ........ }
------------------

I run gcc like this:
gcc -c wastage1d.cpp

The error message of gcc:
------------------
wastage1d.cpp:140: error: cannot declare member function `static void
wastage::Wastage1D::clever_erase(std::vector<T, std::allocator<_CharT>
&, std::vector<typename std::vector<T, std::allocator<_CharT>
::iterator, std::allocator<typename std::vector<T, std::allocator<_CharT> >::iterator> >&, std::vector<T,
std::allocator<_CharT> >&)' to have static linkage
wastage1d.cpp: In static member function `static void
wastage::Wastage1D::clever_erase(std::vector<T, std::allocator<_CharT>&, std::vector<typename std::vector<T, std::allocator<_CharT>
::iterator, std::allocator<typename std::vector<T,

std::allocator<_CharT> >::iterator> >&, std::vector<T,
std::allocator<_CharT> >&)':
------------------

What's wrong?

thanks for your time
May 2 '06 #1
Share this Question
Share on Google+
7 Replies


P: n/a
Chameleon wrote:
This code below compiles fine with VS.2005 but with gcc 3.4.2 not.
------------------
template<class T>
static void Wastage1D::clever_erase(vector<T> &v, vector<typename
vector<T>::iterator> &its, vector<T> &vo)
{ ........ }
------------------

I run gcc like this:
gcc -c wastage1d.cpp

The error message of gcc:
------------------
wastage1d.cpp:140: error: cannot declare member function `static void
wastage::Wastage1D::clever_erase(std::vector<T, std::allocator<_CharT>
>&, std::vector<typename std::vector<T, std::allocator<_CharT>
>::iterator, std::allocator<typename std::vector<T,

std::allocator<_CharT> >::iterator> >&, std::vector<T,
std::allocator<_CharT> >&)' to have static linkage
wastage1d.cpp: In static member function `static void
wastage::Wastage1D::clever_erase(std::vector<T, std::allocator<_CharT>
>&, std::vector<typename std::vector<T, std::allocator<_CharT>
>::iterator, std::allocator<typename std::vector<T,

std::allocator<_CharT> >::iterator> >&, std::vector<T,
std::allocator<_CharT> >&)':
------------------

What's wrong?


It seems like you put 'static' not only on the member function
declaration, but on the definition too. Drop the one on the definition.

class C
{
static void f();
};

void C::f() // <-- no static here
{
}
Jonathan

May 2 '06 #2

P: n/a
Jonathan Mcdougall wrote:
Chameleon wrote:
This code below compiles fine with VS.2005 but with gcc 3.4.2 not.
------------------
template<class T>
static void Wastage1D::clever_erase(vector<T> &v, vector<typename
vector<T>::iterator> &its, vector<T> &vo)
{ ........ }
------------------

I run gcc like this:
gcc -c wastage1d.cpp

The error message of gcc:
------------------
wastage1d.cpp:140: error: cannot declare member function `static void
wastage::Wastage1D::clever_erase(std::vector<T, std::allocator<_CharT>
>&, std::vector<typename std::vector<T, std::allocator<_CharT>
>::iterator, std::allocator<typename std::vector<T,

std::allocator<_CharT> >::iterator> >&, std::vector<T,
std::allocator<_CharT> >&)' to have static linkage
wastage1d.cpp: In static member function `static void
wastage::Wastage1D::clever_erase(std::vector<T, std::allocator<_CharT>
>&, std::vector<typename std::vector<T, std::allocator<_CharT>
>::iterator, std::allocator<typename std::vector<T,

std::allocator<_CharT> >::iterator> >&, std::vector<T,
std::allocator<_CharT> >&)':
------------------

What's wrong?


It seems like you put 'static' not only on the member function
declaration, but on the definition too. Drop the one on the definition.

class C
{
static void f();
};

void C::f() // <-- no static here
{
}


ok and thanks!
but I have one last problem (the same: VS.2005 does, gcc doesn't)
-------------------
template<class T>
void Wastage1D::clever_erase(vector<T> &v, vector<typename
vector<T>::iterator> &its, vector<T> &vo)
{
// ....... code .......
vector<T>::iterator cur = its.front(), curo = its.front();
vector<typename vector<T>::iterator>::iterator itscur = its.begin();
// ....... code .......
}
-------------------

gcc fails to compile with this message:
-------------------
wastage1d.cpp:148: error: expected `;' before "cur"
wastage1d.cpp:149: error: expected `;' before "itscur"
-------------------

how can I put ";" before "cur" or "itscur"?

after all these, I believe, for cross-platform code, its better to use
first gcc (until the completion of the program) and after VS.

thank you
May 2 '06 #3

P: n/a
Chameleon wrote:
template<class T>
void Wastage1D::clever_erase(vector<T> &v, vector<typename
vector<T>::iterator> &its, vector<T> &vo)
{
// ....... code .......
vector<T>::iterator cur = its.front(), curo = its.front();
vector<typename vector<T>::iterator>::iterator itscur = its.begin();
// ....... code .......
}
-------------------

gcc fails to compile with this message:
-------------------
wastage1d.cpp:148: error: expected `;' before "cur"
wastage1d.cpp:149: error: expected `;' before "itscur"
-------------------

how can I put ";" before "cur" or "itscur"?
:)

Either you are inattentive or you didn't write part of the code because
the answer is right there :

vector<typename vector<T>::iterator>::iterator itscur
^^^^^^^^^^^

When a name depends on a template parameter, you must use typename to
indicate to the compiler that what follows is a type name and nothing
else. So your code becomes:

typename vector<T>::iterator cur = its.front(), curo = its.front();
typename vector<typename vector<T>::iterator>::iterator itscur =
its.begin();
after all these, I believe, for cross-platform code, its better to use
first gcc (until the completion of the program) and after VS.


The more conforming the compiler is, the better, yes.
Jonathan

May 2 '06 #4

P: n/a
simpler sample:

---------------
#include <vector>
using namespace std;

template <class T> class c1 {
public:
static void c() {
vector<T>::iterator f;
}
};

int main() { c1<int> c; }
---------------

if I change for instance the line
vector<T>::iterator f;
with
vector<T> f;
works.

the error message:
--------------
test.cpp:7: error: expected `;' before "f"
--------------
May 2 '06 #5

P: n/a
Jonathan Mcdougall wrote:
Chameleon wrote:
template<class T>
void Wastage1D::clever_erase(vector<T> &v, vector<typename
vector<T>::iterator> &its, vector<T> &vo)
{
// ....... code .......
vector<T>::iterator cur = its.front(), curo = its.front();
vector<typename vector<T>::iterator>::iterator itscur = its.begin();
// ....... code .......
}
-------------------

gcc fails to compile with this message:
-------------------
wastage1d.cpp:148: error: expected `;' before "cur"
wastage1d.cpp:149: error: expected `;' before "itscur"
-------------------

how can I put ";" before "cur" or "itscur"?


:)

Either you are inattentive or you didn't write part of the code because
the answer is right there :

vector<typename vector<T>::iterator>::iterator itscur
^^^^^^^^^^^

When a name depends on a template parameter, you must use typename to
indicate to the compiler that what follows is a type name and nothing
else. So your code becomes:

typename vector<T>::iterator cur = its.front(), curo = its.front();
typename vector<typename vector<T>::iterator>::iterator itscur =
its.begin();
after all these, I believe, for cross-platform code, its better to use
first gcc (until the completion of the program) and after VS.


The more conforming the compiler is, the better, yes.


it works! it works!
thanks a lot

Finally, the problem is that, I know only the basics about templates in
C++. The problem in above code, was only a symptom...

I must read.
May 2 '06 #6

P: n/a
Chameleon wrote:
simpler sample:

---------------
#include <vector>
using namespace std;

template <class T> class c1 {
public:
static void c() {
vector<T>::iterator f;
}
};

int main() { c1<int> c; }
---------------

if I change for instance the line
vector<T>::iterator f;
with
vector<T> f;
works.

the error message:
--------------
test.cpp:7: error: expected `;' before "f"
--------------


Is that a question? If so, ask it plainly and remember to quote the
message are answering to.

The problem with the line

vector<T>::iterator f;

is that the compiler, at the time it sees this line, may be unable to
know what the definition of vector<> is for that specific T. Since
templates may be specialized, vector<A>::iterator could be a type and
vector<B>::iterator could be an object:

class A {};
class B {};

template <class T>
class vector;

template<>
class vector<A>
{
public:
typedef int iterator; // just an example
};

template<>
class vector<B>
{
public:
int iterator;
};

template <class T>
void f()
{
vector<T>::iterator itor; // what is 'iterator' here?
}

The language says that in this case, vector<T>::iterator sould be
considered as an object, not a type (it may be either one here,
depending on whether T is A or B). Adding 'typename' in front indicates
that 'iterator' is a type, not an object.

template <class T>
void f()
{
typename vector<T>::iterator itor; // 'iterator' is a type
}

As for using vector<T> directly, it poses no problem to the compiler
since that name must be declared before it is used. It is easy for the
compiler to decide whether it is a type or not.
Jonathan

May 2 '06 #7

P: n/a
Chameleon wrote:
This code below compiles fine with VS.2005 but with gcc 3.4.2 not.
------------------
template<class T>
static void Wastage1D::clever_erase(vector<T> &v, vector<typename
vector<T>::iterator> &its, vector<T> &vo)
{ ........ }
------------------

I run gcc like this:
gcc -c wastage1d.cpp

<snip>

Use 'gcc' to compile & link C code, and 'g++' to
compile & link C++ code. So...

g++ -c wastage1d.cpp

produces 'wastage1d.o' (or 'wastage1d.obj' on Windows?).
Than later, to link the executable 'wastage' (all on
one line - linux/unix example)...

g++ wastage1d.o other.o another.o -lsomelib -lanotherlib
-owastage

'g++' invokes the linker, passing it the correct options
and default libs. The syntax may differ slightly on Windows,
read the gcc/g++ docs.

Larry
May 2 '06 #8

This discussion thread is closed

Replies have been disabled for this discussion.