definition of template static default-constructed data members impossible?

Discussion in 'C++' started by Paul, Dec 9, 2004.

  1. Paul

    Paul Guest

    Hi,

    I have a problem with the C++ spec 14.7.3.15 (see
    http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14761 for relevant
    discussion).

    It seems that the code (below) is impossible to get right, as you
    cannot define a static data member of a template class if it ONLY has
    a default-initializer...

    the following code generates the following error:

    $ g++ -Wall -W -pedantic -ansi -o test test.cpp
    /tmp/ccnWckun.o(.text+0x11): In function `main':
    : undefined reference to `foo<goo>::f'
    collect2: ld returned 1 exit status

    a real-life example of a 'goo' is boost::mutex, that can only be
    default-constructed. I wanted it to be a static data member of a
    template class, but I can't seem to define it. i can declare it just
    fine, but not define.

    Paul



    struct goo
    {
    goo() : y(20) {}
    int y;
    private:
    goo(const goo&);
    };

    template< typename S >
    struct foo {
    static goo f;
    };

    template< >
    goo foo< goo >::f;

    #include<iostream>

    int main() {
    foo<goo> x;
    std::cerr << x.f.y << std::endl;
    }
     
    Paul, Dec 9, 2004
    #1
    1. Advertising

  2. "Paul" <> wrote...
    > I have a problem with the C++ spec 14.7.3.15 (see
    > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14761 for relevant
    > discussion).
    >
    > It seems that the code (below) is impossible to get right, as you
    > cannot define a static data member of a template class if it ONLY has
    > a default-initializer...


    That seems right (unfortunately). You could still use a pointer initialised
    from dynamic memory or a reference to that pointer (if you don't mind a
    small
    memory leak):

    template<typename S> struct foo {
    static goo& f;
    };

    template<>
    goo& foo<goo>::f = *(new goo());

    > [...]


    V
     
    Victor Bazarov, Dec 9, 2004
    #2
    1. Advertising

  3. Paul

    Guest

    I suppose thats a solution, but then you have to deal with pointers and
    remember to destroy it.

    I thought of a local static variable, ie

    static Goo& goo() { static Goo g; return &g; }

    course that means i have to call goo() if i want to access it.

    This is unbelievable, don't many people hit this problem?
    default-constructed-only classes aren't that uncommon.

    Paul
     
    , Dec 9, 2004
    #3
  4. Hi Paul,

    unfortunately, I can't help you with this problem, but I have a question,
    regarding this code snippet:

    > template< >
    > goo foo< goo >::f;


    Usually, you would only write:
    goo foo<goo>::f;

    Whats's the leading template<> good for? Is this, because the concerning
    declaration is still part of the class declaration or something like that?

    Just curious.

    Regards,
    Matthias
     
    Matthias =?ISO-8859-1?Q?K=E4ppler?=, Dec 9, 2004
    #4
  5. wrote in news: in
    comp.lang.c++:

    > I suppose thats a solution, but then you have to deal with pointers and
    > remember to destroy it.
    >
    > I thought of a local static variable, ie
    >
    > static Goo& goo() { static Goo g; return &g; }
    >
    > course that means i have to call goo() if i want to access it.
    >
    > This is unbelievable, don't many people hit this problem?
    > default-constructed-only classes aren't that uncommon.
    >


    Not really, you're only hitting the problem because you are explicitly
    specializing a static member, usually the un-specialized version would
    do fine:

    template < typename S >
    goo foo< S >::f;

    The above is a defenition, unlike the uninitialized explicit
    specialization in your original post that is only a declaration.

    Rob.
    --
    http://www.victim-prime.dsl.pipex.com/
     
    Rob Williscroft, Dec 9, 2004
    #5
  6. Matthias K├Ąppler wrote in news:cp8v5u$2u8$02$-online.com in
    comp.lang.c++:

    > Hi Paul,
    >
    > unfortunately, I can't help you with this problem, but I have a
    > question, regarding this code snippet:
    >
    >> template< >
    >> goo foo< goo >::f;

    >
    > Usually, you would only write:
    > goo foo<goo>::f;
    >


    That is how to define a member of an explicity specalized class.

    The template <> syntax is used as the OP is explicitly specializing
    a member of an unspecialized class.

    > Whats's the leading template<> good for? Is this, because the
    > concerning declaration is still part of the class declaration or
    > something like that?
    >


    Yep its something like that :).

    Rob.
    --
    http://www.victim-prime.dsl.pipex.com/
     
    Rob Williscroft, Dec 9, 2004
    #6
  7. Paul

    Paul Guest

    Paul, Dec 9, 2004
    #7
  8. Paul

    Paul Guest

    Rob Williscroft wrote:

    > Not really, you're only hitting the problem because you are

    explicitly
    > specializing a static member, usually the un-specialized version

    would
    > do fine:
    >
    > template < typename S >
    > goo foo< S >::f;
    >
    > The above is a defenition, unlike the uninitialized explicit
    > specialization in your original post that is only a declaration.


    Fantastic thanks, this works :)

    But one question: I assume this creates a different instance per
    templated instance, NOT that there is a single static instance for a
    class of data members.
    Right?

    For the benefit of others like me, the above goes in a header file like
    any other template...

    Thanks
    Paul
     
    Paul, Dec 10, 2004
    #8
  9. Paul wrote in news:
    in comp.lang.c++:

    > Rob Williscroft wrote:
    >
    >> Not really, you're only hitting the problem because you are

    > explicitly
    >> specializing a static member, usually the un-specialized version

    > would
    >> do fine:
    >>
    >> template < typename S >
    >> goo foo< S >::f;
    >>
    >> The above is a defenition, unlike the uninitialized explicit
    >> specialization in your original post that is only a declaration.

    >
    > Fantastic thanks, this works :)
    >
    > But one question: I assume this creates a different instance per
    > templated instance, NOT that there is a single static instance for a
    > class of data members.
    > Right?


    The will be a seperate instance of this member for every "S" that the
    class template foo< S > is instantiated with.

    If you want one instance shared between every instantiated type then
    derive foo< S > from a base:

    struct foo_base
    {
    static goo f;
    };

    goo foo_base::f; /* *NOT* in a header file ! */

    template < typename S >
    class foo : private foo_base
    {
    public:

    using foo_base::f; /* hoist foo_base::f to public */
    };

    >
    > For the benefit of others like me, the above goes in a header file like
    > any other template...
    >


    Yes.

    Rob.
    --
    http://www.victim-prime.dsl.pipex.com/
     
    Rob Williscroft, Dec 10, 2004
    #9
    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. JFCM
    Replies:
    4
    Views:
    5,767
  2. Kristoffer Vinther

    Default constructed random access iteratators

    Kristoffer Vinther, May 17, 2005, in forum: C++
    Replies:
    1
    Views:
    350
    Ron Natalie
    May 18, 2005
  3. Clemens Hintze
    Replies:
    0
    Views:
    299
    Clemens Hintze
    Nov 7, 2005
  4. aaragon
    Replies:
    12
    Views:
    1,322
    aaragon
    Nov 8, 2006
  5. Replies:
    5
    Views:
    284
    Michele Dondi
    Jun 30, 2006
Loading...

Share This Page