 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Artem Alimarine Guest
|
Posted: Thu Jun 22, 2006 4:01 pm Post subject: static template member |
|
|
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
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
|
Posted: Fri Jun 23, 2006 3:03 pm Post subject: Re: static template member |
|
|
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
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
|
Posted: Fri Jun 23, 2006 3:09 pm Post subject: Re: static template member |
|
|
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
|
Posted: Fri Jun 23, 2006 3:09 pm Post subject: Re: static template member |
|
|
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
|
Posted: Fri Jun 23, 2006 3:13 pm Post subject: Re: static template member |
|
|
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
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
|
Posted: Sat Jun 24, 2006 2:36 pm Post subject: Re: static template member |
|
|
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
|
Posted: Sun Jun 25, 2006 6:46 pm Post subject: Re: static template member |
|
|
"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
|
Posted: Tue Jun 27, 2006 4:16 pm Post subject: Re: static template member |
|
|
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 |
|
 |
|
|
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
|
|