initialization of a static member of a template class

Discussion in 'C++' started by Ralf Goertz, Mar 5, 2010.

  1. Ralf Goertz

    Ralf Goertz Guest

    Hi,

    I'm not sure whether this only applies to template classes but that's
    where I stumbled over it.

    Usually I try to inizialize variables not by assignment but by ctor,
    i.e. "int i(0)" instead of "int i=0". But this doesn't work in the
    following code:

    #include <functional>

    using namespace std;

    template<class T> struct Odd : public unary_function<T,bool> {
    bool operator() (T i) const {
    return i%2;
    }
    };

    template<class T> class X {
    static Odd<T> odd;
    };

    template<class T> Odd<T> X<T>::eek:dd(Odd<T>()); // (*)

    int main() {
    X<int> x;
    Odd<long> odder(Odd<long>()); // (**)
    return 0;
    }


    Comeau gives:

    "ComeauTest.c", line 15: error: declaration is incompatible with "Odd<T>
    X<T>::eek:dd"
    (declared at line 12)
    template<class T> Odd<T> X<T>::eek:dd(Odd<T>());
    ^

    g++ gives:

    x.cc:15: error: no ‘Odd<T> X<T>::eek:dd(Odd<T> (*)())’ member function declared in
    class ‘X<T>’


    If I replace (*) with

    template<class T> Odd<T> X<T>::eek:dd=Odd<T>();

    it works, which is even odder since the ctor construction works in the
    line marked by (**). By the way, why is it necessary to have a static
    member of a template initialized at all?
     
    Ralf Goertz, Mar 5, 2010
    #1
    1. Advertising

  2. Ralf Goertz

    joseph cook Guest

    On Mar 5, 7:26 am, Ralf Goertz <> wrote:

    > If I replace (*) with
    >
    > template<class T> Odd<T> X<T>::eek:dd=Odd<T>();
    >
    > it works, which is even odder since the ctor construction works in the
    > line marked by (**). By the way, why is it necessary to have a static
    > member of a template initialized at all?


    Why not just
    template<class T> Odd<T> X<T>::eek:dd ?

    You just need to define the variable somewhere. The parser is
    getting confused thinking that you are defining a new function as
    opposed to calling the default constructor of Odd<T>

    Joe
     
    joseph cook, Mar 5, 2010
    #2
    1. Advertising

  3. Ralf Goertz

    Ralf Goertz Guest

    joseph cook wrote:

    > On Mar 5, 7:26 am, Ralf Goertz <> wrote:
    >
    >> If I replace (*) with
    >>
    >> template<class T> Odd<T> X<T>::eek:dd=Odd<T>();
    >>
    >> it works, which is even odder since the ctor construction works in the
    >> line marked by (**). By the way, why is it necessary to have a static
    >> member of a template initialized at all?

    >
    > Why not just
    > template<class T> Odd<T> X<T>::eek:dd ?


    Yes, that works here. But what if I don't want the default ctor?

    > You just need to define the variable somewhere. The parser is
    > getting confused thinking that you are defining a new function as
    > opposed to calling the default constructor of Odd<T>


    Hm, I figured that could be the problem. But that means that—strictly
    speaking—it is not an error but the comiler is too stupid?
     
    Ralf Goertz, Mar 5, 2010
    #3
  4. Ralf Goertz wrote:
    > joseph cook wrote:
    >
    >> On Mar 5, 7:26 am, Ralf Goertz <> wrote:
    >>
    >>> If I replace (*) with
    >>>
    >>> template<class T> Odd<T> X<T>::eek:dd=Odd<T>();
    >>>
    >>> it works, which is even odder since the ctor construction works in the
    >>> line marked by (**). By the way, why is it necessary to have a static
    >>> member of a template initialized at all?

    >> Why not just
    >> template<class T> Odd<T> X<T>::eek:dd ?

    >
    > Yes, that works here. But what if I don't want the default ctor?
    >


    Then you would pass the parameter(s), like this :
    template<class T> Odd<T> X<T>::eek:dd( p1, p2 );
    and not like this:
    template<class T> Odd<T> X<T>::eek:dd( Odd<T>( p1, p2 ) );
     
    Vladimir Jovic, Mar 5, 2010
    #4
  5. Ralf Goertz

    Ralf Goertz Guest

    Vladimir Jovic wrote:

    > Ralf Goertz wrote:
    >> joseph cook wrote:
    >>
    >>> On Mar 5, 7:26 am, Ralf Goertz <> wrote:
    >>>
    >>>> If I replace (*) with
    >>>>
    >>>> template<class T> Odd<T> X<T>::eek:dd=Odd<T>();
    >>>>
    >>>> it works, which is even odder since the ctor construction works in the
    >>>> line marked by (**). By the way, why is it necessary to have a static
    >>>> member of a template initialized at all?
    >>> Why not just
    >>> template<class T> Odd<T> X<T>::eek:dd ?

    >>
    >> Yes, that works here. But what if I don't want the default ctor?
    >>

    >
    > Then you would pass the parameter(s), like this :
    > template<class T> Odd<T> X<T>::eek:dd( p1, p2 );
    > and not like this:
    > template<class T> Odd<T> X<T>::eek:dd( Odd<T>( p1, p2 ) );


    Ouch, of course, thanks.

    Remains the question why it is necessary to have that initialization line.
     
    Ralf Goertz, Mar 5, 2010
    #5
  6. Ralf Goertz

    James Kanze Guest

    On 5 Mar, 14:04, Ralf Goertz <> wrote:
    > joseph cook wrote:
    > > On Mar 5, 7:26 am, Ralf Goertz <> wrote:


    > >> If I replace (*) with


    > >> template<class T> Odd<T> X<T>::eek:dd=Odd<T>();


    > >> it works, which is even odder since the ctor construction
    > >> works in the line marked by (**). By the way, why is it
    > >> necessary to have a static member of a template initialized
    > >> at all?


    > > Why not just
    > > template<class T> Odd<T> X<T>::eek:dd ?


    > Yes, that works here. But what if I don't want the default ctor?


    > > You just need to define the variable somewhere. The
    > > parser is getting confused thinking that you are defining a
    > > new function as opposed to calling the default constructor
    > > of Odd<T>


    > Hm, I figured that could be the problem. But that means
    > that—strictly speaking—it is not an error but the comiler is
    > too stupid?


    No. That means that the declaration grammar for C++ is
    ambiguous, and that the standard says that in such cases, you've
    just tried to declare a function. It's a well-known (and
    frequent) problem, sometimes referred to as C++'s mosts
    embaressing parse.

    An extra set of parentheses will remove the ambiguity:

    template< typename T > Odd<T> X<T>::eek:dd((Odd<T>()));

    --
    James Kanze
     
    James Kanze, Mar 5, 2010
    #6
    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. Michael Klatt
    Replies:
    6
    Views:
    2,699
    Jesper Madsen
    Nov 18, 2003
  2. Siemel Naran
    Replies:
    4
    Views:
    808
    Micah Cowan
    Jan 12, 2005
  3. Frederiek
    Replies:
    1
    Views:
    382
    Thomas Tutone
    Sep 14, 2006
  4. ALiX
    Replies:
    20
    Views:
    772
    Victor Bazarov
    Jul 27, 2007
  5. dolphin
    Replies:
    3
    Views:
    1,349
    Pete Becker
    Dec 5, 2007
Loading...

Share This Page