This is a multi-part message in MIME format.

------=_NextPart_000_0019_01C51AB5.A1F0E910
Content-Type: text/plain;
charset="gb2312"
Content-Transfer-Encoding: quoted-printable


In the following program, why won't member static MyTypeInfo =
TypeInfoBase<A>::TI be instantiated?

Ben


/////////////////////////////////

#include <list>
#include <iostream>
#include <typeinfo>

using namespace std;

list<MyTypeInfo&> ListOfTypes;

struct MyTypeInfo // purpose: to record a type
{
type_info& tid; =20

MyTypeInfo(type_info& ti)
:tid(ti)
{
ListOfTypes.push_back(*this);
cout << ti.name();
}
};

template <typename T>
class TypeInfoBase
{
private:
TypeInfoBase();

public:
static typename MyTypeInfo TI;

};

template <typename T>
MyTypeInfo TypeInfoBase<T>::TI =3D MyTypeInfo(typeid(T));

template <typename T>
class TypeTrait{};

class A
{
//...
};

// specialize TypeTrait<A> to construct the static object
template <> class TypeTrait<A>: public TypeInfoBase<A>{};

int main(int argc, char* argv[])
{
// TypeInfoBase<A> should have been instantiated at this point
// and so should TypeInfoBase<A>::TI be constructed.
// But it is not! Why??

return 0;
}


------=_NextPart_000_0019_01C51AB5.A1F0E910
Content-Type: text/html;
charset="gb2312"
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=3DContent-Type content=3D"text/html; charset=3Dgb2312">
<META content=3D"MSHTML 6.00.2800.1106" name=3DGENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=3D#ffffff>
<DIV>&nbsp;</DIV>
<DIV><FONT face=3DArial>In the following program, why won't =
member&nbsp;<U>static=20
MyTypeInfo TypeInfoBase&lt;A&gt;::TI</U> be instantiated?</FONT></DIV>
<DIV><FONT face=3DArial></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial>Ben</FONT></DIV>
<DIV><FONT face=3D"Courier New" color=3D#008000 =
size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3D"Courier New" size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3D"Courier New" color=3D#008000=20
size=3D2>/////////////////////////////////</FONT></DIV>
<DIV><FONT size=3D2></FONT><FONT size=3D2></FONT><FONT =
size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3D"Courier New" size=3D2><FONT =
color=3D#0000ff>#include</FONT>=20
&lt;list&gt;</FONT><BR><FONT size=3D2><FONT face=3D"Courier New"><FONT=20
color=3D#0000ff>#include</FONT> &lt;iostream&gt;<BR><FONT=20
color=3D#0000ff>#include</FONT> &lt;typeinfo&gt;</FONT></FONT></DIV>
<DIV><FONT face=3D"Courier New" size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2><FONT face=3D"Courier New"><FONT =
color=3D#0000ff>using=20
namespace</FONT> std;</FONT></FONT></DIV>
<DIV><FONT face=3D"Courier New" size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3D"Courier New" size=3D2>list&lt;MyTypeInfo&amp;&gt;=20
ListOfTypes;</FONT></DIV>
<DIV><FONT face=3D"Courier New" size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2><FONT face=3D"Courier New"><FONT =
color=3D#0000ff>struct</FONT>=20
MyTypeInfo <FONT color=3D#008000>// purpose: to record a=20
type</FONT><BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;type_info&amp;=20
tid;&nbsp;&nbsp;&nbsp; </FONT></FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2><FONT face=3D"Courier New">&nbsp;&nbsp;&nbsp;=20
MyTypeInfo(type_info&amp; ti)</FONT></FONT></DIV>
<DIV><FONT size=3D2><FONT face=3D"Courier New">&nbsp;&nbsp;&nbsp;=20
:tid(ti)<BR>&nbsp;&nbsp;&nbsp; {<BR></FONT></FONT><FONT size=3D2><FONT=20
face=3D"Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
ListOfTypes.push_back(*this);</FONT></FONT></DIV>
<DIV><FONT size=3D2><FONT face=3D"Courier New">&nbsp;&nbsp;&nbsp; =
&nbsp;&nbsp;&nbsp;=20
cout &lt;&lt; ti.name();<BR>&nbsp;&nbsp;&nbsp; =
}<BR>};</FONT></FONT></DIV>
<DIV><FONT face=3D"Courier New" size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2><FONT face=3D"Courier New"><FONT =
color=3D#0000ff>template</FONT>=20
&lt;<FONT color=3D#0000ff>typename</FONT> T&gt;<BR>&nbsp;&nbsp;&nbsp; =
<FONT=20
color=3D#0000ff>class</FONT> TypeInfoBase<BR>&nbsp;&nbsp;&nbsp;=20
{<BR>&nbsp;&nbsp;&nbsp; <FONT=20
color=3D#0000ff>private</FONT>:<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; =

TypeInfoBase();</FONT></FONT></DIV>
<DIV><FONT face=3D"Courier New" size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2><FONT face=3D"Courier New">&nbsp;&nbsp;&nbsp; <FONT=20
color=3D#0000ff>public</FONT>:<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;=20
<STRONG><FONT color=3D#0000ff>static</FONT> <FONT =
color=3D#0000ff>typename</FONT>=20
MyTypeInfo TI;</STRONG></FONT></FONT></DIV>
<DIV><FONT face=3D"Courier New" size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3D"Courier New" size=3D2>&nbsp;&nbsp;&nbsp; =
};</FONT></DIV>
<DIV><FONT face=3D"Courier New" size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2><FONT face=3D"Courier New"><STRONG><FONT=20
color=3D#0000ff>template</FONT> &lt;<FONT =
color=3D#0000ff>typename</FONT>=20
T&gt;<BR></STRONG>&nbsp;&nbsp;&nbsp; <STRONG>MyTypeInfo=20
TypeInfoBase&lt;T&gt;::TI =3D MyTypeInfo(<FONT=20
color=3D#0000ff>typeid</FONT>(T));</STRONG></FONT></FONT></DIV>
<DIV><FONT face=3D"Courier New" size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2><FONT face=3D"Courier New"><FONT =
color=3D#0000ff>template</FONT>=20
&lt;<FONT color=3D#0000ff>typename</FONT> T&gt;</FONT></FONT></DIV>
<DIV><FONT face=3D"Courier New" size=3D2>&nbsp;&nbsp;&nbsp; <FONT=20
color=3D#0000ff>class</FONT> TypeTrait{};</FONT></DIV>
<DIV><FONT face=3D"Courier New" size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2><FONT face=3D"Courier New"><FONT =
color=3D#0000ff>class</FONT>=20
A</FONT></FONT></DIV>
<DIV><FONT face=3D"Courier New" size=3D2>{</FONT></DIV>
<DIV><FONT size=3D2><FONT face=3D"Courier New">&nbsp;&nbsp;&nbsp; <FONT=20
color=3D#008000>//...</FONT></FONT></FONT></DIV>
<DIV><FONT face=3D"Courier New" size=3D2>};</FONT></DIV>
<DIV><FONT face=3D"Courier New" size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3D"Courier New" color=3D#008000 size=3D2>// specialize=20
TypeTrait&lt;A&gt; to construct the static object</FONT></DIV>
<DIV><FONT face=3D"Courier New"><STRONG><FONT size=3D2><FONT=20
color=3D#0000ff>template</FONT> &lt;&gt; </FONT><FONT size=3D2><FONT=20
color=3D#0000ff>class</FONT> TypeTrait&lt;A&gt;: <FONT =
color=3D#0000ff>public</FONT>=20
TypeInfoBase&lt;A&gt;{</FONT><FONT =
size=3D2>};</FONT></STRONG></FONT></DIV>
<DIV><FONT face=3D"Courier New" size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2><FONT face=3D"Courier New"><FONT =
color=3D#0000ff>int</FONT>=20
main(<FONT color=3D#0000ff>int</FONT> argc, <FONT =
color=3D#0000ff>char</FONT>*=20
argv[])<BR>{</FONT></FONT></DIV>
<DIV><FONT face=3D"Courier New" color=3D#008000 =
size=3D2>&nbsp;&nbsp;&nbsp; //=20
TypeInfoBase&lt;A&gt; should have been instantiated at this =
point</FONT></DIV>
<DIV><FONT face=3D"Courier New" color=3D#008000 =
size=3D2>&nbsp;&nbsp;&nbsp; // and so=20
should TypeInfoBase&lt;A&gt;::TI be constructed.</FONT></DIV>
<DIV><FONT face=3D"Courier New" color=3D#008000 =
size=3D2>&nbsp;&nbsp;&nbsp; // But it=20
is not! Why??</FONT></DIV>
<DIV><FONT size=3D2><BR><FONT face=3D"Courier New">&nbsp;&nbsp;&nbsp; =
<FONT=20
color=3D#0000ff>return</FONT> 0;<BR>}</FONT></FONT></DIV>
<DIV><FONT face=3D"Courier New" size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3D"Courier New" =
size=3D2></FONT>&nbsp;</DIV></BODY></HTML>

------=_NextPart_000_0019_01C51AB5.A1F0E910--

Re: specialized class template point of instantiation by Victor

Victor
Thu Feb 24 08:26:40 CST 2005

ben wrote:
>
> In the following program, why won't member _static MyTypeInfo
> TypeInfoBase<A>::TI_ be instantiated?
>
> Ben
>
>
> /////////////////////////////////
>
> #include <list>
> #include <iostream>
> #include <typeinfo>
>
> using namespace std;
>
> list<MyTypeInfo&> ListOfTypes;
>
> struct MyTypeInfo // purpose: to record a type
> {
> type_info& tid;
>
> MyTypeInfo(type_info& ti)
> :tid(ti)
> {
> ListOfTypes.push_back(*this);
> cout << ti.name();
> }
> };
>
> template <typename T>
> class TypeInfoBase
> {
> private:
> TypeInfoBase();
>
> public:
> *static typename MyTypeInfo TI;*
>
> };
>
> *template <typename T>
> * *MyTypeInfo TypeInfoBase<T>::TI = MyTypeInfo(typeid(T));*
>
> template <typename T>
> class TypeTrait{};
>
> class A
> {
> //...
> };
>
> // specialize TypeTrait<A> to construct the static object
> *template <> class TypeTrait<A>: public TypeInfoBase<A>{};*

Specialization does not cause instantiation.

>
> int main(int argc, char* argv[])
> {
> // TypeInfoBase<A> should have been instantiated at this point

Why do you say that it "should have been"?

> // and so should TypeInfoBase<A>::TI be constructed.
> // But it is not! Why??

You never used it. Try writing code that actually uses that var.

>
> return 0;
> }
>
>

V

Re: specialized class template point of instantiation by Tom

Tom
Thu Feb 24 08:59:48 CST 2005

ben wrote:
>
> In the following program, why won't member _static MyTypeInfo
> TypeInfoBase<A>::TI_ be instantiated?
>
> Ben
>
>
> /////////////////////////////////
>
> #include <list>
> #include <iostream>
> #include <typeinfo>
>
> using namespace std;
>
> list<MyTypeInfo&> ListOfTypes;
>
> struct MyTypeInfo // purpose: to record a type
> {
> type_info& tid;
>
> MyTypeInfo(type_info& ti)
> :tid(ti)
> {
> ListOfTypes.push_back(*this);
> cout << ti.name();
> }
> };
>
> template <typename T>
> class TypeInfoBase
> {
> private:
> TypeInfoBase();
>
> public:
> *static typename MyTypeInfo TI;*

"typename" is not required there, and possibly not even allowed there
according to the standard.

>
> };
>
> *template <typename T>
> * *MyTypeInfo TypeInfoBase<T>::TI = MyTypeInfo(typeid(T));*
>
> template <typename T>
> class TypeTrait{};
>
> class A
> {
> //...
> };
>
> // specialize TypeTrait<A> to construct the static object
> *template <> class TypeTrait<A>: public TypeInfoBase<A>{};*

Why do you think that would construct the static object?

>
> int main(int argc, char* argv[])
> {
> // TypeInfoBase<A> should have been instantiated at this point
> // and so should TypeInfoBase<A>::TI be constructed.
> // But it is not! Why??

Static members of templates are only implicitly instantiated *if they
are used in a context that requires a definition*, just as with all
implicit instantiation (see 14.7.1/1). So you can trigger it by doing
something like:

MyTypeInfo const& dummy = TypeInfoBase<A>::TI;

or you can explicitly instantiate it. e.g. at namespace scope, something
like:

template MyTypeInfo TypeInfoBase<A>::TI;

but simply instantiating the class template *won't* instantiate its members.

Tom

Re: specialized class template point of instantiation by ben

ben
Thu Feb 24 17:02:03 CST 2005

Thanks Tom! Now it really makes sense. I have been testing the code and
found only some of the members are instantiated.

But anyway I would like the static member instantiated rather implicitly. I
don'w want to declare objects (notice the private constructor), neither do I
want to use macros. What are my options? viz to tell the compiler not to
optimize off the static definition much the same way a "volatile" keyword
does to unused variables.

> ben wrote:
> >
> > In the following program, why won't member _static MyTypeInfo
> > TypeInfoBase<A>::TI_ be instantiated?
> >
> > Ben
> >
> >
> > /////////////////////////////////
> >
> > #include <list>
> > #include <iostream>
> > #include <typeinfo>
> >
> > using namespace std;
> >
> > list<MyTypeInfo&> ListOfTypes;
> >
> > struct MyTypeInfo // purpose: to record a type
> > {
> > type_info& tid;
> >
> > MyTypeInfo(type_info& ti)
> > :tid(ti)
> > {
> > ListOfTypes.push_back(*this);
> > cout << ti.name();
> > }
> > };
> >
> > template <typename T>
> > class TypeInfoBase
> > {
> > private:
> > TypeInfoBase();
> >
> > public:
> > *static typename MyTypeInfo TI;*
>
> "typename" is not required there, and possibly not even allowed there
> according to the standard.
>
> >
> > };
> >
> > *template <typename T>
> > * *MyTypeInfo TypeInfoBase<T>::TI = MyTypeInfo(typeid(T));*
> >
> > template <typename T>
> > class TypeTrait{};
> >
> > class A
> > {
> > //...
> > };
> >
> > // specialize TypeTrait<A> to construct the static object
> > *template <> class TypeTrait<A>: public TypeInfoBase<A>{};*
>
> Why do you think that would construct the static object?
>
> >
> > int main(int argc, char* argv[])
> > {
> > // TypeInfoBase<A> should have been instantiated at this point
> > // and so should TypeInfoBase<A>::TI be constructed.
> > // But it is not! Why??
>
> Static members of templates are only implicitly instantiated *if they
> are used in a context that requires a definition*, just as with all
> implicit instantiation (see 14.7.1/1). So you can trigger it by doing
> something like:
>
> MyTypeInfo const& dummy = TypeInfoBase<A>::TI;
>
> or you can explicitly instantiate it. e.g. at namespace scope, something
> like:
>
> template MyTypeInfo TypeInfoBase<A>::TI;
>
> but simply instantiating the class template *won't* instantiate its
members.
>
> Tom



Re: specialized class template point of instantiation by Tom

Tom
Mon Feb 28 03:49:57 CST 2005

ben wrote:
> Thanks Tom! Now it really makes sense. I have been testing the code and
> found only some of the members are instantiated.
>
> But anyway I would like the static member instantiated rather implicitly. I
> don'w want to declare objects (notice the private constructor), neither do I
> want to use macros. What are my options? viz to tell the compiler not to
> optimize off the static definition much the same way a "volatile" keyword
> does to unused variables.

Your only option is probably explicit instantiation of the static
member. It's a language feature, so there's not much you can do about it.

Tom

Re: specialized class template point of instantiation by ben

ben
Mon Feb 28 05:30:49 CST 2005

Thank you Tom! Yea I figoured out as much!

Ben

> ben wrote:
> > Thanks Tom! Now it really makes sense. I have been testing the code and
> > found only some of the members are instantiated.
> >
> > But anyway I would like the static member instantiated rather
implicitly. I
> > don'w want to declare objects (notice the private constructor), neither
do I
> > want to use macros. What are my options? viz to tell the compiler not to
> > optimize off the static definition much the same way a "volatile"
keyword
> > does to unused variables.
>
> Your only option is probably explicit instantiation of the static
> member. It's a language feature, so there's not much you can do about it.
>
> Tom