definition of template static default-constructed data members impossible?

P

Paul

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;
}
 
V

Victor Bazarov

Paul said:
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 said:

V
 
E

elegant_dice

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
 
M

Matthias =?ISO-8859-1?Q?K=E4ppler?=

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
 
R

Rob Williscroft

wrote in 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.
 
R

Rob Williscroft

Matthias Käppler wrote in in
comp.lang.c++:
Hi Paul,

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


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

That is how to define a member of an explicity specalized 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.
 
P

Paul

Rob said:
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
 
R

Rob Williscroft

Paul wrote in in comp.lang.c++:
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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,961
Messages
2,570,131
Members
46,689
Latest member
liammiller

Latest Threads

Top