 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Chimanrao Guest
|
Posted: Wed Nov 15, 2006 6:28 am Post subject: question on static member for class template |
|
|
hi
here is a code snippet:
#include <iostream>
#include <string>
struct type_record
{
type_record(const std::string& str)
{
std::cout << str << "\n";
}
};
template <typename T>
class helper
{
private: // nothing uses the following member
static type_record reg;
};
template <typename T>
volatile type_record
helper<T>::reg(typeid(T).name());
template class helper<int>;
template class helper<float>;
template class helper<double>;
class mytest : public helper<char>
{
};
int main() {return 0;}
The output of this program is
int
float
double
no constructor is called for the static object for mytest class. why is
this?
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Viper Craft Guest
|
Posted: Thu Nov 16, 2006 3:57 am Post subject: Re: question on static member for class template |
|
|
You do not use mytest class, therefore all members code are
rejected...
And this is explicit instatiation of template class:
template class helper<int>;
template class helper<float>;
template class helper<double>;
Because of clause 14.7.2.7, implies the instantiation of all os its
members...
--
[ 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: Thu Nov 16, 2006 4:14 am Post subject: Re: question on static member for class template |
|
|
James Kanze wrote:
| Quote: | Chimanrao wrote:
here is a code snippet:
#include <iostream
#include <string
struct type_record
{
type_record(const std::string& str)
{
std::cout << str << "\n";
}
};
template <typename T
class helper
{
private: // nothing uses the following member
static type_record reg;
};
In order to trigger an instatiation, it is necessary to use the
object in some way. Perhaps by adding a constructor to helper:
helper() { ® }
(Even this won't suffice in the exact code above, but in almost
all real cases, it should be enough.)
|
Adding pointless statements to a program is hardly the best way to
instantiate a template class or one of its members. Aside from missing
a semicolon, the expression "®" has no side effects. So the compiler
may issue a warning or even optimize it away completely - and therefore
not end up instantiating the object as intended. An even bigger problem
- and the reason that I would not recommend this technique - is that
the meaning of this statement has completely diverged from its purpose.
In other words, it's not at all clear what this expression is doing -
and why it should be remain - in the program. So even if the statement
survives the compiler, there's a good chance that another programmer
may remove it in the furure - and would do so for the same reason - the
statement doesn't appear to do anything.
To instantiate a template class object explicitly, it is best to use
the syntax that the C++ language has defined for this very purpose.
Explicit instantiation of a complete class - or of an individual member
- does not require that the instantiated object (or member) also be
"used" somewhere in the program.
Here is the explicit instantiation of helper<char>::ref:
template type_record helper<char>::reg;
Grreg
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Seungbeom Kim Guest
|
Posted: Thu Nov 16, 2006 8:04 am Post subject: Re: question on static member for class template |
|
|
James Kanze wrote:
| Quote: |
Because you never define the static object.
In the case of a template class, two things are necessary for
the static object to be defined: you must provide a template
definition for it, and you must do something which causes the
definition to be instantiated. Neither of these is present in
the code you show.
|
I think the OP did provide a definition for the static object:
template <typename T>
volatile type_record
helper<T>::reg(typeid(T).name());
even though the added 'volatile' specifier causes it not to match
the original definition. Removing 'volatile', it's fine.
| Quote: | Providing the template definition is easy: after the definition
of class helper, add a line:
template< typename T
type_record helper< T >::reg ;
|
Your definition doesn't compile because type_record doesn't have
a default constructor; you should construct reg with a string.
| Quote: | In order to trigger an instatiation, it is necessary to use the
object in some way. Perhaps by adding a constructor to helper:
helper() { ® }
(Even this won't suffice in the exact code above, but in almost
all real cases, it should be enough.)
|
I guess inheriting from a template class does trigger the template
to be instantiated; for example, mytest is derived from helper<char>,
so helper<char> gets instantiated.
Then, do you mean it's not sufficient for instantiating a static
member object of the template class? That is, does instantiating
helper<char> not guarantee instantiating helper<char>::reg? In that
case, is there no standard way to guarantee the instantiation?
--
Seungbeom Kim
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Alberto Ganesh Barbati Guest
|
Posted: Thu Nov 16, 2006 8:10 am Post subject: Re: question on static member for class template |
|
|
Greg Herlihy ha scritto:
| Quote: | James Kanze wrote:
Chimanrao wrote:
#include <iostream
#include <string
struct type_record
{
type_record(const std::string& str)
{
std::cout << str << "\n";
}
};
template <typename T
class helper
{
private: // nothing uses the following member
static type_record reg;
};
In order to trigger an instatiation, it is necessary to use the
object in some way. Perhaps by adding a constructor to helper:
helper() { ® }
(Even this won't suffice in the exact code above, but in almost
all real cases, it should be enough.)
|
In this case this trick it's not necessary, because the OP is using
explicit instantiation of the class template. Explicit instantiation
will always instantiate all class members, including static data members
(§14.7.2/7).
| Quote: | To instantiate a template class object explicitly, it is best to use
the syntax that the C++ language has defined for this very purpose.
Explicit instantiation of a complete class - or of an individual member
- does not require that the instantiated object (or member) also be
"used" somewhere in the program.
Here is the explicit instantiation of helper<char>::ref:
template type_record helper<char>::reg;
|
In the OP's case, this is redundant. As I said before, the static data
member shall already be instantiated by the explicit instantiation of
the class.
James Kanze's trick is useful to force the instantiation of the static
data member even if the class is *implicitly* instantiated. In this case
you suggestion doesn't help.
However, I agree that a statement like "®" is a bit too cryptic
(imagine an HTML expert surprised to see a registered trademark in C++
code ). Moreover, the absence of side-effects might tempt aggressive
compiler to optimize the statement away. Maybe wrapping the idiom inside
a function could make it more readable and avoid the problem. For example:
volatile void* ptr;
template <class T>
inline void force_instantiation_of(T& x) { ptr = &x; }
template <typename T>
class helper
{
public:
~helper() { force_instantiation_of(reg); }
private:
static type_record reg;
};
Notice that force_instantiation_of has a side effect so it can't be
optimized away. However this force_instantiation_of has a non-null cost.
Maybe we could propose a library function that does just that: force an
object to marked as "used" (in the sense that the linker can't strip it
away) without actually doing nothing. What do you think?
Ganesh
--
[ 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
|
|