compiler specific: gcc and templates

Discussion in 'C++' started by Chameleon, May 2, 2006.

  1. Chameleon

    Chameleon Guest

    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
     
    Chameleon, May 2, 2006
    #1
    1. Advertising

  2. 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
     
    Jonathan Mcdougall, May 2, 2006
    #2
    1. Advertising

  3. Chameleon

    Chameleon Guest

    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
     
    Chameleon, May 2, 2006
    #3
  4. 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
     
    Jonathan Mcdougall, May 2, 2006
    #4
  5. Chameleon

    Chameleon Guest

    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"
    --------------
     
    Chameleon, May 2, 2006
    #5
  6. Chameleon

    Chameleon Guest

    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.
     
    Chameleon, May 2, 2006
    #6
  7. 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
     
    Jonathan Mcdougall, May 2, 2006
    #7
  8. 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
     
    Larry I Smith, May 2, 2006
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. JKop
    Replies:
    3
    Views:
    505
  2. Replies:
    8
    Views:
    450
  3. recover
    Replies:
    2
    Views:
    845
    recover
    Jul 25, 2006
  4. ashnin

    GCC 3.4.3 and GCC 4.1.2

    ashnin, Jul 7, 2008, in forum: C++
    Replies:
    1
    Views:
    563
    Michael DOUBEZ
    Jul 7, 2008
  5. werasm
    Replies:
    4
    Views:
    376
    James Kanze
    Nov 30, 2009
Loading...

Share This Page