C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

static template member

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Artem Alimarine
Guest





PostPosted: Thu Jun 22, 2006 4:01 pm    Post subject: static template member Reply with quote



Hi all,

The program below illustrates my problem. It compiles on VC8, also on
GCC 3.4.4. (cygwin special) and on GCC 4.1.0 20060304 (Red Hat 4.1.0-3)

However it does not link with GCCs: the static symbol is not found. I
can make it link by uncommenting the second commented line, but then VC8
will refuse to work. I do not understand why one would need the two
lines with template<> and template to make it work. Looks a bit shamanic
to me.

VC8 works as it is and also when the first commented line is used
instead of template<> ...

My questions are:
Who is right: GCC or VC8?
How do I write such a program in standard-compliant way that works with
both compilers? (

I understand that good old ifdef will do Smile
but ...

Artem

//-------------------------------------------------------------------
template<class T>
struct foo
{
int method(int x) { return 0; }
static foo<T> the_instance;
};

struct bar {
int method() {
return foo<bar>::the_instance.method(1);
}
};

// foo<bar> foo<bar>::the_instance;

//template foo<bar> foo<bar>::the_instance;
template<> foo<bar> foo<bar>::the_instance;

int main() {
bar the_bar;
the_bar.method();
}

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Vladimir Marko
Guest





PostPosted: Fri Jun 23, 2006 3:03 pm    Post subject: Re: static template member Reply with quote



Artem Alimarine wrote:
Quote:
Hi all,

The program below illustrates my problem. It compiles on VC8, also on
GCC 3.4.4. (cygwin special) and on GCC 4.1.0 20060304 (Red Hat 4.1.0-3)

However it does not link with GCCs: the static symbol is not found. I
can make it link by uncommenting the second commented line, but then VC8
will refuse to work. I do not understand why one would need the two
lines with template<> and template to make it work. Looks a bit shamanic
to me.

VC8 works as it is and also when the first commented line is used
instead of template<> ...

My questions are:
Who is right: GCC or VC8?
How do I write such a program in standard-compliant way that works with
both compilers? (

I understand that good old ifdef will do Smile
but ...

Artem

//-------------------------------------------------------------------
template<class T
struct foo
{
int method(int x) { return 0; }
static foo<T> the_instance;
};

struct bar {
int method() {
return foo<bar>::the_instance.method(1);
}
};

// foo<bar> foo<bar>::the_instance;

//template foo<bar> foo<bar>::the_instance;
template<> foo<bar> foo<bar>::the_instance;

int main() {
bar the_bar;
the_bar.method();
}

I'd suggest to define
template <class T> foo<T> foo<T>::the_instance;
but if you really want to use the explicit specialization you should
read 14.7.3 very carefully.

In particular, 14.7.3/15 says
An explicit specialization of a static data member of a template is
a definition if the declaration includes an initializer; otherwise,
it is a declaration. [Note: ...]
So the correct way to _define_ foo<bar>::the_instance is
template<> foo<bar> foo<bar>::instance=foo<bar>();
(And should foo<bar> be non-CopyConstructible you'd need to find
some workaround, say a constructor with a dummy parameter.)

The other problem in your code is that you use foo<bar>::the_instance
before you declare the explicit specialization. According to 14.7.3/6
this makes your code ill-formed without the need for a diagnostic.

Thus, the correct way to write the program is to put the declaration of
the explicit specialization before its first use and define it using
the initializer. gcc 3.3 and 4.0 accept that and I hope the VC8 will
accept it as well.

Vladimir Marko


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Valentin Samko
Guest





PostPosted: Fri Jun 23, 2006 3:09 pm    Post subject: Re: static template member Reply with quote



Artem Alimarine wrote:
Quote:
Hi all,

The program below illustrates my problem. It compiles on VC8, also on
GCC 3.4.4. (cygwin special) and on GCC 4.1.0 20060304 (Red Hat 4.1.0-3)

However it does not link with GCCs: the static symbol is not found. I
can make it link by uncommenting the second commented line, but then VC8
will refuse to work. I do not understand why one would need the two
lines with template<> and template to make it work. Looks a bit shamanic
to me.


That looks like g++ bug. In any case, you can have
template<class T> foo<T> foo<T>::the_instance;
template foo<bar> foo<bar>::the_instance;
which compiles with g++, comeau c++, vc7, vc8, intel c++ :)

--

Valentin Samko - http://www.valentinsamko.com

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Greg Herlihy
Guest





PostPosted: Fri Jun 23, 2006 3:09 pm    Post subject: Re: static template member Reply with quote

Artem Alimarine wrote:
Quote:
Hi all,

The program below illustrates my problem. It compiles on VC8, also on
GCC 3.4.4. (cygwin special) and on GCC 4.1.0 20060304 (Red Hat 4.1.0-3)

However it does not link with GCCs: the static symbol is not found. I
can make it link by uncommenting the second commented line, but then VC8
will refuse to work. I do not understand why one would need the two
lines with template<> and template to make it work. Looks a bit shamanic
to me.

VC8 works as it is and also when the first commented line is used
instead of template<> ...

My questions are:
Who is right: GCC or VC8?

They are both right that the program is wrong.

Quote:
How do I write such a program in standard-compliant way that works with
both compilers? (

By adding what is missing.

Quote:
//-------------------------------------------------------------------
template<class T
struct foo
{
int method(int x) { return 0; }
static foo<T> the_instance;
};

The program is missing the definition of foo's static variable,
the_instance. Whether foo is a class template or not, foo::the_instance
still has to be defined somewhere. It is not.

So adding the missing definition after foo's declaration, fixes the
problem:

template <class T>
foo<T> foo<T>::the_instance;

Greg


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
dan2online
Guest





PostPosted: Fri Jun 23, 2006 3:13 pm    Post subject: Re: static template member Reply with quote

Artem Alimarine wrote:
Quote:
Hi all,

The program below illustrates my problem. It compiles on VC8, also on
GCC 3.4.4. (cygwin special) and on GCC 4.1.0 20060304 (Red Hat 4.1.0-3)

However it does not link with GCCs: the static symbol is not found. I
can make it link by uncommenting the second commented line, but then VC8
will refuse to work. I do not understand why one would need the two
lines with template<> and template to make it work. Looks a bit shamanic
to me.

VC8 works as it is and also when the first commented line is used
instead of template<> ...

My questions are:
Who is right: GCC or VC8?
How do I write such a program in standard-compliant way that works with
both compilers? (

I understand that good old ifdef will do Smile
but ...

Artem

//-------------------------------------------------------------------
template<class T
struct foo
{
int method(int x) { return 0; }
static foo<T> the_instance;
};

struct bar {
int method() {
return foo<bar>::the_instance.method(1);
}
};

// foo<bar> foo<bar>::the_instance;

//template foo<bar> foo<bar>::the_instance;
template<> foo<bar> foo<bar>::the_instance;


template<class T> foo<T> foo<T>::the_instance;

for both compilers.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Michael D. Carney
Guest





PostPosted: Sat Jun 24, 2006 2:36 pm    Post subject: Re: static template member Reply with quote

In article <1151026564.153900.130230 (AT) r2g2000cwb (DOT) googlegroups.com>,

Quote:
The program is missing the definition of foo's static variable,
the_instance. Whether foo is a class template or not, foo::the_instance
still has to be defined somewhere. It is not.

So adding the missing definition after foo's declaration, fixes the
problem:

template <class T
foo<T> foo<T>::the_instance;

Greg


Be careful with that in VC8, however. If you link together a program
that consists of several dlls, and the template is referenced in more
than one of the dlls, each dll that references the template will have
its own instance of the static member of the template. In linux (or any
non-windows OS that I'm aware of), the instance will only exist once in
the program, and each library will reference the same instance (which, I
think, is the way its supposed to work according to the standard).

The upshot of this is that if you're using the foo template above to
implement a generic singleton, you won't get a singleton (i.e. one
instance per process), but rather you'll get one instance per dll, which
is definitely not what you want.

If there's a way around this issue in VC8, please follow up here. The
only way I found that works is to force the instance to be defined in
only one dll by doing some macro tricks.

- Mike.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Gene Bushuyev
Guest





PostPosted: Sun Jun 25, 2006 6:46 pm    Post subject: Re: static template member Reply with quote

"Michael D. Carney" <mcarney (AT) mathworks (DOT) com> wrote in message
news:mcarney-380F53.09165723062006 (AT) news (DOT) mathworks.com...
Quote:
In article <1151026564.153900.130230 (AT) r2g2000cwb (DOT) googlegroups.com>,

The program is missing the definition of foo's static variable,
the_instance. Whether foo is a class template or not, foo::the_instance
still has to be defined somewhere. It is not.

So adding the missing definition after foo's declaration, fixes the
problem:

template <class T
foo<T> foo<T>::the_instance;

Greg


Be careful with that in VC8, however. If you link together a program
that consists of several dlls, and the template is referenced in more
than one of the dlls, each dll that references the template will have
its own instance of the static member of the template. In linux (or any
non-windows OS that I'm aware of), the instance will only exist once in
the program, and each library will reference the same instance (which, I
think, is the way its supposed to work according to the standard).



The standard doesn't say anything about dynamically linked libraries. Since dlls
are shared by multiple processes, which may have nothing to do with each other,
it only stands to reason that each one should get its own copy of static data,
unless you explicitly put the data in shared segment.

--
Gene Bushuyev (www.gbresearch.com)
----------------------------------------------------------------
To see what is in front of one's nose needs a constant struggle ~ George Orwell


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
kanze
Guest





PostPosted: Tue Jun 27, 2006 4:16 pm    Post subject: Re: static template member Reply with quote

Michael D. Carney wrote:
Quote:
In article <1151026564.153900.130230 (AT) r2g2000cwb (DOT) googlegroups.com>,

The program is missing the definition of foo's static
variable, the_instance. Whether foo is a class template or
not, foo::the_instance still has to be defined somewhere. It
is not.

So adding the missing definition after foo's declaration,
fixes the problem:

template <class T
foo<T> foo<T>::the_instance;

Be careful with that in VC8, however. If you link together a
program that consists of several dlls, and the template is
referenced in more than one of the dlls, each dll that
references the template will have its own instance of the
static member of the template. In linux (or any non-windows OS
that I'm aware of), the instance will only exist once in the
program, and each library will reference the same instance
(which, I think, is the way its supposed to work according to
the standard).

According to the standard, as soon as you use dynamic linking,
you have undefined behavior. An implementation can do whatever
it wants. I'm not too familiar with Windows, but I know that
under Solaris, you can get both behaviors, depending on what you
want. (Most of the time, of course, you want to isolate the
dynamiclyl linked objects as much as possible; the fact that one
dynamically linked object happens to use some particular
global variable in its implementation shouldn't interfere with
any other dynamically linked object which might accidentally use
a global object of the same type.)

Quote:
The upshot of this is that if you're using the foo template
above to implement a generic singleton, you won't get a
singleton (i.e. one instance per process), but rather you'll
get one instance per dll, which is definitely not what you
want.

It depends, but I would say that most of the time, it is
definitly what you want. The fact that my plugin happens to use
some particular singleton (with a particular name) shouldn't
interfere with other plugins, even if they accidentally use the
same name.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.