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 

question on static member for class template

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





PostPosted: Wed Nov 15, 2006 6:28 am    Post subject: question on static member for class template Reply with quote



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





PostPosted: Thu Nov 16, 2006 3:57 am    Post subject: Re: question on static member for class template Reply with quote



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





PostPosted: Thu Nov 16, 2006 4:14 am    Post subject: Re: question on static member for class template Reply with quote



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() { &reg }

(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 "&reg" 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





PostPosted: Thu Nov 16, 2006 8:04 am    Post subject: Re: question on static member for class template Reply with quote

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() { &reg }

(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





PostPosted: Thu Nov 16, 2006 8:10 am    Post subject: Re: question on static member for class template Reply with quote

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() { &reg }

(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 "&reg;" is a bit too cryptic
(imagine an HTML expert surprised to see a registered trademark in C++
code Very Happy). 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
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.