473,221 Members | 2,122 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,221 software developers and data experts.

Initialization of static varible in class template

I have a C++ template class which contains a static variable whose
construction registers the class with a map. Something like this:

template <typename T>
class M {
static Registrar<M> registrar;
};

The constructor of Registrar does the registering when it is initialized.

My problem is, I can't get this to work for a general class M<T>. I can
get it to work for a specific instance, like M<double>, by including the
initialization definition in the .cpp file:

Registrar< M<double> > M<double>::registrar;

but the general case doesn't work:

template <typename T>
Registrar< M<T> > M<T>::registrar;

It doesn't matter where I put this code --- in the header or .cpp file
--- the Registrar constructor does not get called.

Can anyone tell me where I should put the definition, and whether I need
to do something special with gcc (v3.3) options?

Drew
Jul 22 '05 #1
7 2439
Drew McCormack wrote:
I have a C++ template class which contains a static variable whose
construction registers the class with a map. Something like this:

template <typename T>
class M {
static Registrar<M> registrar;
};

The constructor of Registrar does the registering when it is initialized.

My problem is, I can't get this to work for a general class M<T>. I can
get it to work for a specific instance, like M<double>, by including the
initialization definition in the .cpp file:

Registrar< M<double> > M<double>::registrar;

but the general case doesn't work:

template <typename T>
Registrar< M<T> > M<T>::registrar;

It doesn't matter where I put this code --- in the header or .cpp file
--- the Registrar constructor does not get called.

Can anyone tell me where I should put the definition, and whether I need
to do something special with gcc (v3.3) options?


All you need to do is use that 'registrar' somehow. If it's not used,
it's not created. 14.7.1/7 says "The implicit instantiation of a class
template does not cause any static data members of that class to be
implicitly instantiated."

What works, as you described, is the _explicit_ instantiation. Implicit
one doesn't.

As to gcc options, please ask in a gcc newsgroup. Compiler options are
off-topic here.

Victor
Jul 22 '05 #2
Victor Bazarov wrote:
Drew McCormack wrote:
I have a C++ template class which contains a static variable whose
construction registers the class with a map. Something like this:

template <typename T>
class M {
static Registrar<M> registrar;
};

The constructor of Registrar does the registering when it is initialized.

My problem is, I can't get this to work for a general class M<T>. I
can get it to work for a specific instance, like M<double>, by
including the initialization definition in the .cpp file:

Registrar< M<double> > M<double>::registrar;

but the general case doesn't work:

template <typename T>
Registrar< M<T> > M<T>::registrar;

It doesn't matter where I put this code --- in the header or .cpp file
--- the Registrar constructor does not get called.

Can anyone tell me where I should put the definition, and whether I
need to do something special with gcc (v3.3) options?


Hi Victor,
You were right, I needed to use the static variable in my code.
Nonetheless, I am a bit confused as to why this is necessary. Here is why:
All you need to do is use that 'registrar' somehow. If it's not used,
it's not created. 14.7.1/7 says "The implicit instantiation of a class
template does not cause any static data members of that class to be
implicitly instantiated."

I do explicitly instantiate the class template: I use M<double> in my
code, for example. What I wasn't doing is using the static variable
explicitly. Should this be necessary, or is explicitly instantiating the
class template enough?

Drew
Jul 22 '05 #3
Victor Bazarov wrote:
Drew McCormack wrote:
I have a C++ template class which contains a static variable whose
construction registers the class with a map. Something like this:

template <typename T>
class M {
static Registrar<M> registrar;
};

The constructor of Registrar does the registering when it is initialized.

My problem is, I can't get this to work for a general class M<T>. I
can get it to work for a specific instance, like M<double>, by
including the initialization definition in the .cpp file:

Registrar< M<double> > M<double>::registrar;

but the general case doesn't work:

template <typename T>
Registrar< M<T> > M<T>::registrar;

It doesn't matter where I put this code --- in the header or .cpp file
--- the Registrar constructor does not get called.

Can anyone tell me where I should put the definition, and whether I
need to do something special with gcc (v3.3) options?

All you need to do is use that 'registrar' somehow.

One more question: Do you have any suggestions for a clean way to use
the registrar instance in order to force the compiler to create it? At
the moment I am just calling a method of registrar that does nothing
inside the destructor of M<T>, but maybe there is a cleaner way to do it.

Drew
Jul 22 '05 #4
Victor Bazarov wrote:
Drew McCormack wrote:
Victor Bazarov wrote:
Drew McCormack wrote:

I have a C++ template class which contains a static variable whose
construction registers the class with a map. Something like this:

template <typename T>
class M {
static Registrar<M> registrar;
};

The constructor of Registrar does the registering when it is
initialized.

My problem is, I can't get this to work for a general class M<T>. I
can get it to work for a specific instance, like M<double>, by
including the initialization definition in the .cpp file:

Registrar< M<double> > M<double>::registrar;

but the general case doesn't work:

template <typename T>
Registrar< M<T> > M<T>::registrar;

It doesn't matter where I put this code --- in the header or .cpp
file --- the Registrar constructor does not get called.

Can anyone tell me where I should put the definition, and whether I
need to do something special with gcc (v3.3) options?


All you need to do is use that 'registrar' somehow.

One more question: Do you have any suggestions for a clean way to use
the registrar instance in order to force the compiler to create it? At
the moment I am just calling a method of registrar that does nothing
inside the destructor of M<T>, but maybe there is a cleaner way to do it.

What is the purpose of the registrar? Do you intend in the future to
query it somehow to find out how many instances/classes have been created
in the program? If you do query it, you will get your "use" and it will
be instantiated. Until then, put debugging its constructor aside.

Victor

The registrar registers the class in a map, which is used for
serialization. The registrar constructor does this, and it needs to do
it once for each registered class. By including a static instance of
registrar in each class, I intend that the registrar registers the
class, inserting it in the map, before the main program starts.
Jul 22 '05 #5
Victor Bazarov wrote:
Drew McCormack wrote:
Victor Bazarov wrote:
Drew McCormack wrote:

I have a C++ template class which contains a static variable whose
construction registers the class with a map. Something like this:

template <typename T>
class M {
static Registrar<M> registrar;
};

The constructor of Registrar does the registering when it is
initialized.

My problem is, I can't get this to work for a general class M<T>. I
can get it to work for a specific instance, like M<double>, by
including the initialization definition in the .cpp file:

Registrar< M<double> > M<double>::registrar;

but the general case doesn't work:

template <typename T>
Registrar< M<T> > M<T>::registrar;

It doesn't matter where I put this code --- in the header or .cpp
file --- the Registrar constructor does not get called.

Can anyone tell me where I should put the definition, and whether I
need to do something special with gcc (v3.3) options?


Hi Victor,
You were right, I needed to use the static variable in my code.
Nonetheless, I am a bit confused as to why this is necessary. Here is
why:

All you need to do is use that 'registrar' somehow. If it's not used,
it's not created. 14.7.1/7 says "The implicit instantiation of a class
template does not cause any static data members of that class to be
implicitly instantiated."

I do explicitly instantiate the class template: I use M<double> in my
code, for example.

Didn't you initially say that you only had a problem with non-specialised
(not explicitly instantiated) variations of the template? I took it that
you didn't have any problem with 'M<double>::registrar' (and you're not
supposed to, AFAIUI).
> What I wasn't doing is using the static variable

explicitly. Should this be necessary, or is explicitly instantiating
the class template enough?

It's enough to explicitly instantiate the class. But was it the problem
you were running into?

Victor

It works if I explicitly instantiate the static variable:

M<double>::registrar;

But it doesn't work if I just explicitly instantiate the class M:

M<double> mInstance;

The latter does not lead to the static M<double>::registrar being
created. I thought it should, but it doesn't.

Drew
Jul 22 '05 #6
Drew McCormack wrote:
Victor Bazarov wrote:
Drew McCormack wrote:
Victor Bazarov wrote:

Drew McCormack wrote:

> I have a C++ template class which contains a static variable whose
> construction registers the class with a map. Something like this:
>
> template <typename T>
> class M {
> static Registrar<M> registrar;
> };
>
> The constructor of Registrar does the registering when it is
> initialized.
>
> My problem is, I can't get this to work for a general class M<T>.
> I can get it to work for a specific instance, like M<double>, by
> including the initialization definition in the .cpp file:
>
> Registrar< M<double> > M<double>::registrar;
>
> but the general case doesn't work:
>
> template <typename T>
> Registrar< M<T> > M<T>::registrar;
>
> It doesn't matter where I put this code --- in the header or .cpp
> file --- the Registrar constructor does not get called.
>
> Can anyone tell me where I should put the definition, and whether I
> need to do something special with gcc (v3.3) options?

Hi Victor,
You were right, I needed to use the static variable in my code.
Nonetheless, I am a bit confused as to why this is necessary. Here is
why:
All you need to do is use that 'registrar' somehow. If it's not used,
it's not created. 14.7.1/7 says "The implicit instantiation of a class
template does not cause any static data members of that class to be
implicitly instantiated."

I do explicitly instantiate the class template: I use M<double> in my
code, for example.


Didn't you initially say that you only had a problem with non-specialised
(not explicitly instantiated) variations of the template? I took it that
you didn't have any problem with 'M<double>::registrar' (and you're not
supposed to, AFAIUI).
> What I wasn't doing is using the static variable

explicitly. Should this be necessary, or is explicitly instantiating
the class template enough?


It's enough to explicitly instantiate the class. But was it the problem
you were running into?

Victor


It works if I explicitly instantiate the static variable:

M<double>::registrar;

But it doesn't work if I just explicitly instantiate the class M:

M<double> mInstance;

The latter does not lead to the static M<double>::registrar being
created. I thought it should, but it doesn't.


I think you're confused what is an instantiation of what. When you write

M<double> mInstance;

it's an [explicit] instantiation of the class M<double>, but it's not
an explicit instantiation of the template. For the template, it's very
_implicit_. An explicit instantiation of the template would be

template class M<double>;

Yes, it's supposed to work when you explicitly initialise the static data
member itself. However, it should also work when you instantiate the
template explicitly, without explicit instantiation of the static data
member. Example:

template<class T> struct A { static int sa; }; // template definition
template<class T> int A<T>::sa; // definition of the static member

// the following is the explicit instantiation of A<int>
template struct A<int>; // causes A<int>::sa to be instantiated, no
// matter whether you ever have an object of
// type A<int>

// the following is an explicit instantiation of A<char>::sa
template int A<char>::sa;

// the following is an implicit instantiation of A<double> _and_
// an [explicit] instantiation of an object of A<double> type.
A<double> ad; // does NOT instantiate A<double>::sa

What you need to distinguish here is instantiating a template and that
of the resulting class. When you instantiate a class, you create one
object (instance) of that class, which allocates some memory, etc. But
it doesn't cause any code to be created. When you instantiate a template,
the code for _functions_ is created and also static data members are
created (instantiated).

Victor
Jul 22 '05 #7
Victor Bazarov wrote:
Drew McCormack wrote:
Victor Bazarov wrote:
Drew McCormack wrote:

Victor Bazarov wrote:

> Drew McCormack wrote:
>
>> I have a C++ template class which contains a static variable whose
>> construction registers the class with a map. Something like this:
>>
>> template <typename T>
>> class M {
>> static Registrar<M> registrar;
>> };
>>
>> The constructor of Registrar does the registering when it is
>> initialized.
>>
>> My problem is, I can't get this to work for a general class M<T>.
>> I can get it to work for a specific instance, like M<double>, by
>> including the initialization definition in the .cpp file:
>>
>> Registrar< M<double> > M<double>::registrar;
>>
>> but the general case doesn't work:
>>
>> template <typename T>
>> Registrar< M<T> > M<T>::registrar;
>>
>> It doesn't matter where I put this code --- in the header or .cpp
>> file --- the Registrar constructor does not get called.
>>
>> Can anyone tell me where I should put the definition, and whether
>> I need to do something special with gcc (v3.3) options?
>
>
>
>
>

Hi Victor,
You were right, I needed to use the static variable in my code.
Nonetheless, I am a bit confused as to why this is necessary. Here
is why:

>
> All you need to do is use that 'registrar' somehow. If it's not used,
> it's not created. 14.7.1/7 says "The implicit instantiation of a
> class
> template does not cause any static data members of that class to be
> implicitly instantiated."


I do explicitly instantiate the class template: I use M<double> in
my code, for example.


Didn't you initially say that you only had a problem with
non-specialised
(not explicitly instantiated) variations of the template? I took it
that
you didn't have any problem with 'M<double>::registrar' (and you're not
supposed to, AFAIUI).

> What I wasn't doing is using the static variable

explicitly. Should this be necessary, or is explicitly instantiating
the class template enough?


It's enough to explicitly instantiate the class. But was it the problem
you were running into?

Victor

It works if I explicitly instantiate the static variable:

M<double>::registrar;

But it doesn't work if I just explicitly instantiate the class M:

M<double> mInstance;

The latter does not lead to the static M<double>::registrar being
created. I thought it should, but it doesn't.

I think you're confused what is an instantiation of what. When you write

M<double> mInstance;

it's an [explicit] instantiation of the class M<double>, but it's not
an explicit instantiation of the template. For the template, it's very
_implicit_. An explicit instantiation of the template would be

template class M<double>;

Yes, it's supposed to work when you explicitly initialise the static data
member itself. However, it should also work when you instantiate the
template explicitly, without explicit instantiation of the static data
member. Example:

template<class T> struct A { static int sa; }; // template definition
template<class T> int A<T>::sa; // definition of the static member

// the following is the explicit instantiation of A<int>
template struct A<int>; // causes A<int>::sa to be instantiated, no
// matter whether you ever have an object of
// type A<int>

// the following is an explicit instantiation of A<char>::sa
template int A<char>::sa;

// the following is an implicit instantiation of A<double> _and_
// an [explicit] instantiation of an object of A<double> type.
A<double> ad; // does NOT instantiate A<double>::sa

What you need to distinguish here is instantiating a template and that
of the resulting class. When you instantiate a class, you create one
object (instance) of that class, which allocates some memory, etc. But
it doesn't cause any code to be created. When you instantiate a template,
the code for _functions_ is created and also static data members are
created (instantiated).

Victor

OK, now I get it. Thanks. I wasn't up with the explicit/implicit
definitions. Thanks for making that clear.

Cheers,
Drew
Jul 22 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Gianni Mariani | last post by:
I posted a gcc bug http://gcc.gnu.org/bugzilla/show_bug.cgi?id=13332 here is the text: ----------------------------------------------------------- This code will compile fine but fail on...
5
by: gbs | last post by:
Isn't this legal code to initialize a static member of a template class? template <class T> class TemplatedClassT { static int staticMember_; };
6
by: Kyle | last post by:
Hi, I have a library containing some global Variable. However, it seems that when the library is a static lib the initialization of the global var does not happen. I could not find any answer in...
8
by: Robert A Riedel | last post by:
I have an application that requires a DLL and an executable that uses the DLL, both of which were implemented in Visual C++ using unmanged code. Both the executable and the DLL are linked with...
4
by: mnowosad | last post by:
As far I know, static variables are tied to AppDomain scopes. So, every time an executing code within an AppDomain references a class for the the first time since the AppDomain was created/loaded,...
11
by: ALiX | last post by:
Hi! My template class has a const static data member, which is used by the constructor. It seems that the program does not produce the correct result. Either it is the fault of the compiler (gcc...
6
by: Christof Warlich | last post by:
Hi, the few lines of code below show different results depending on the compiler version (gcc-2.95 versus gcc-3.3 and later): gcc-2.95 first initializes d (line 9) and then t (line 8), as...
15
by: akomiakov | last post by:
Is there a technical reason why one can't initialize a cost static non- integral data member in a class?
4
by: aaragon | last post by:
Hi everyone, I have a linking error when using gcc4.2 and static member variables. The class template definition is something around the following: template<> class Element<L2_t: public...
1
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...
0
by: VivesProcSPL | last post by:
Obviously, one of the original purposes of SQL is to make data query processing easy. The language uses many English-like terms and syntax in an effort to make it easy to learn, particularly for...
0
by: jianzs | last post by:
Introduction Cloud-native applications are conventionally identified as those designed and nurtured on cloud infrastructure. Such applications, rooted in cloud technologies, skillfully benefit from...
0
by: mar23 | last post by:
Here's the situation. I have a form called frmDiceInventory with subform called subfrmDice. The subform's control source is linked to a query called qryDiceInventory. I've been trying to pick up the...
0
by: abbasky | last post by:
### Vandf component communication method one: data sharing ​ Vandf components can achieve data exchange through data sharing, state sharing, events, and other methods. Vandf's data exchange method...
2
by: jimatqsi | last post by:
The boss wants the word "CONFIDENTIAL" overlaying certain reports. He wants it large, slanted across the page, on every page, very light gray, outlined letters, not block letters. I thought Word Art...
0
by: stefan129 | last post by:
Hey forum members, I'm exploring options for SSL certificates for multiple domains. Has anyone had experience with multi-domain SSL certificates? Any recommendations on reliable providers or specific...
1
by: davi5007 | last post by:
Hi, Basically, I am trying to automate a field named TraceabilityNo into a web page from an access form. I've got the serial held in the variable strSearchString. How can I get this into the...
0
by: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.