Re: question on static member for class template
Alberto Ganesh Barbati wrote:
Greg Herlihy ha scritto:
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).
Although the original program does instantiate three Helper template
classes explicitly - it does not explicitly instantiate Helper<char> -
the template class whose "reg" static member is the missing object.
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.
As noted above, there is no explicit instantiation of Helper<char>
elsewhere in the program, so an explicit instantiation of its reg
static object is not in fact redundant.
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.
On the contrary - my suggestion to instantiate the Helper<char>::reg
static object by itself - and to do so without also instantiating every
other method and member of the Helper<char> template class - is the
most precise, most economical and most surefire way to ensure the
existence of the currently-missing object.
Now, it could well be the case that in the distant past, when the
Standard was still evolving and support of templates among C++
compilers was spotty, that it was in fact necessary to resort to a hack
like the one described in order to instantiate a particular template
class or one of its member objects. But those days are long past. I
can't envision a modern C++ compiler lacking support for explicit
instantiation.
Explicitly instantating Helper<char>::reg static member is t
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 :-D). 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:
...
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?
It's completely unnecessary. After all, C++ supports explicit
instantiation of a static member of a class template:
"A member function, member class or static data member of a class
template can be explicitly instantiated from the member definition
associated with its class template." [?14.7.2/1]
and my suggestion does nothing more than to demonstrate that fact.
Greg
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]