Re: Forcing instantiation of a static member of a template - c++
This is a discussion on Re: Forcing instantiation of a static member of a template - c++ ; On 24 Okt., 20:24, Jiri Palecek <jpale...@web.de> wrote:
> template <class T>
> class A
> {
> public:
> struct Reg { Reg(); };
> static const Reg reg;
> A();
>
> };
>
> template <class T>
...
-
Re: Forcing instantiation of a static member of a template
On 24 Okt., 20:24, Jiri Palecek <jpale...@web.de> wrote:
> template <class T>
> class A
> {
> public:
> struct Reg { Reg(); };
> static const Reg reg;
> A();
>
> };
>
> template <class T>
> const typename A<T>::Reg A<T>::reg;
>
> template <class T>
> A<T>::A() { ® }
>
> However, that's really ugly, and I'd like not to rely on hacks like that.
What happens here that you consider this to be a "hack"?
The first problem I see is the lack of a more exact
description for which scenarios you want the registration
to occur? Just in those cases, when an object A<T>
is created during the runtime of the program?
Which-ever definition you will give, there will be the
problem that the pure usage of the type name will
not lead to such registration, e.g. by doing this:
typedef A<int> MyA;
void foo(A<std::string>&);
> But if I use an explicit instantiation:
>
> ... class A same as above ...
>
> template <class T>
> const typename A<T>::Reg A<T>::reg;
>
> template <class T>
> A<T>::A() { template static const A<T>::Reg A<T>::reg; }
>
> I get errors from the compiler. Intel says "explicit instantiation is not
> allowed here", gcc says even more cryptic syntax error "; expected
> before 'template'".
The compiler is right, this is definitively *not* an
explicit instantiation. Actually I'm not sure that I
understand your indent: Why do you define a non-local
A<T>::reg *and* try to define a local static variable
of type A<T>::Reg? If you properly want to do the last
thing, you simply write this:
template <class T>
A<T>::A() { static const Reg reg; }
Of course, this can lead to other problems, if A has more
than one c'tor - each local static inside those c'tors
belongs to another Reg object.
> However, the standard says that
>
> 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.
>
> and that the definition of the instantiated member shall be in scope at the
> point of the explicit instantiation, which (I think) is true in this case.
> So am I missing something or do all the compiler writers get it wrong?
The compiler writers are correct, and the standard hastens to add the
following in [temp.explicit]/5:
"[..] An explicit instantiation for a member of a class template is
placed
in the namespace where the enclosing class template is defined.[..]"
Your attempt to provide an explicit instantiation in a function scope
is not supported - and what do you want to you realize with this?
Greetings from Bremen,
Daniel Krügler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
-
Re: Forcing instantiation of a static member of a template
Daniel Krügler wrote:
> On 24 Okt., 20:24, Jiri Palecek <jpale...@web.de> wrote:
>> template <class T>
>> class A
>> {
>> public:
>> struct Reg { Reg(); };
>> static const Reg reg;
>> A();
>>
>> };
>>
>> template <class T>
>> const typename A<T>::Reg A<T>::reg;
>>
>> template <class T>
>> A<T>::A() { ® }
>>
>> However, that's really ugly, and I'd like not to rely on hacks like that.
>
> What happens here that you consider this to be a "hack"?
First, it is not very readable. Second, even if the standard says the
Reg::Reg() constructor call may not be elided in this case, the linker is
more often than I'd wish keen to do things like that.
> The first problem I see is the lack of a more exact
> description for which scenarios you want the registration
> to occur? Just in those cases, when an object A<T>
> is created during the runtime of the program?
This is one possibility, although there are scenarios where this doesn't
suffice (eg. if Reg registers the class to some factory which is the only
one that can create the instances). What I meant was that A<T>::reg would
be instantiated whenever a program contains a call to A<T>(). (There are
even more general possibilities - like whenever class A<T> is instantiated,
or whenever A<T>::anything is instantiated.
> Which-ever definition you will give, there will be the
> problem that the pure usage of the type name will
> not lead to such registration, e.g. by doing this:
>
> typedef A<int> MyA;
> void foo(A<std::string>&);
But this does not force an instantiation of A<string> anyway, so even in my
wildest dreams I would not demand the static member here.
>> But if I use an explicit instantiation:
>>
>> ... class A same as above ...
>>
>> template <class T>
>> const typename A<T>::Reg A<T>::reg;
>>
>> template <class T>
>> A<T>::A() { template static const A<T>::Reg A<T>::reg; }
>>
>> I get errors from the compiler. Intel says "explicit instantiation is not
>> allowed here", gcc says even more cryptic syntax error "; expected
>> before 'template'".
>
> The compiler is right, this is definitively *not* an
> explicit instantiation. Actually I'm not sure that I
It is an explicit instantiation, at least syntactically. The syntax of
explicit instantiation is
"template" declaration
and nothing else can begin with "template" not followed by "<". Moreover, it
is quite similar to the example in [temp.explicit]/2:
template void Array<int>::mf();
> understand your indent: Why do you define a non-local
> A<T>::reg *and* try to define a local static variable
> of type A<T>::Reg? If you properly want to do the last
> thing, you simply write this:
>
> template <class T>
> A<T>::A() { static const Reg reg; }
No, I do not want this.
> Of course, this can lead to other problems, if A has more
> than one c'tor - each local static inside those c'tors
> belongs to another Reg object.
Exactly, moreover, this changes the time when Reg() constructor is run.
>> However, the standard says that
>>
>> 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.
>>
>> and that the definition of the instantiated member shall be in scope at
>> the point of the explicit instantiation, which (I think) is true in this
>> case. So am I missing something or do all the compiler writers get it
>> wrong?
>
> The compiler writers are correct, and the standard hastens to add the
> following in [temp.explicit]/5:
>
> "[..] An explicit instantiation for a member of a class template is
> placed
> in the namespace where the enclosing class template is defined.[..]"
Sorry, but I think this clause only states that wherever you instantiate,
the instantiation will be created in the namespace enclosing the
definition. The example for this clause shows instantiating a class a
different namespace, which would not make sense if it were prohibited by
the same clause.
> Your attempt to provide an explicit instantiation in a function scope
> is not supported - and what do you want to you realize with this?
?? (I don't totally understand)
I want the thing I mentioned in the very beginning, to instantiate a member
of a class template whenever other member, or the whole template, was
instantiated.
Or, put another way, the standard says in [temp.explicit]/1:
"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."
How and where can I use this rule?
Regards
Jiri Palecek
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
-
Re: Forcing instantiation of a static member of a template
On 28 Okt., 02:11, Jiri Palecek <jpale...@web.de> wrote:
> Daniel Krügler wrote:
> > What happens here that you consider this to be a "hack"?
>
> First, it is not very readable. Second, even if the standard says the
> Reg::Reg() constructor call may not be elided in this case, the linker is
> more often than I'd wish keen to do things like that.
That is the first time I have heart that lack of readability
is a specific signal for a hack ;-)
If the linker can't handle this, this is a linker bug
and you should inform your vendor.
> > The compiler is right, this is definitively *not* an
> > explicit instantiation. Actually I'm not sure that I
>
> It is an explicit instantiation, at least syntactically. The syntax of
> explicit instantiation is
>
> "template" declaration
>
> and nothing else can begin with "template" not followed by "<".
Not all syntactic valid constructs are supported language
features. As a side note, it has already been recognized by
issue
http://www.open-std.org/jtc1/sc22/wg...ctive.html#293
that the current syntax for explicit instantiations is
too permissive.
> Moreover, it
> is quite similar to the example in [temp.explicit]/2:
>
> template void Array<int>::mf();
I see no such similarity, mf is defined in namespace scope
as it should.
Consider your syntactic construct again:
template <class T>
A<T>::A() { template static const A<T>::Reg A<T>::reg; }
What is the meaning of static here? Does it specify
a storage duration or a linkage? Further-on I see
nothing in the definition of this entity that is
related to an instantiation. In contrast, we are still
in a dependent context here.
>From this follows another difficulty: Which meaning had
your construction, if I provide an explicit specialization
for A<T>::A() given some replacement for T, e.g.
template<> A<int>::A(){}
?
> > The compiler writers are correct, and the standard hastens to add the
> > following in [temp.explicit]/5:
>
> > "[..] An explicit instantiation for a member of a class template is
> > placed
> > in the namespace where the enclosing class template is defined.[..]"
>
> Sorry, but I think this clause only states that wherever you instantiate,
> the instantiation will be created in the namespace enclosing the
> definition. The example for this clause shows instantiating a class a
> different namespace, which would not make sense if it were prohibited by
> the same clause.
I don't share your interpretation, and it seems that the
committee interprets it quite closely to mine in
http://www.open-std.org/jtc1/sc22/wg...efects.html#44
"All uses of the phrase "in the namespace" in the IS mean "directly
in the namespace," not in a scope nested within the namespace."
Of-course this is my personal interpretation and I suggest
that you post a defect report on comp.std.c++ if you
still think that the standard is wrong or incompletely
specified in this regard.
> I want the thing I mentioned in the very beginning, to instantiate a member
> of a class template whenever other member, or the whole template, was
> instantiated.
As shown above I can't see any valid explicit instantiation here.
> Or, put another way, the standard says in [temp.explicit]/1:
>
> "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."
>
> How and where can I use this rule?
It says, that it will use the member definition given by the
primary template to create the explicit instantiation.
HTH and Greetings from Bremen,
Daniel Krügler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
-
Re: Forcing instantiation of a static member of a template
On 29 Okt., 02:28, Daniel Krügler <daniel.krueg...@googlemail.com>
wrote:
> On 28 Okt., 02:11, Jiri Palecek <jpale...@web.de> wrote:
> Consider your syntactic construct again:
>
> template <class T>
> A<T>::A() { template static const A<T>::Reg A<T>::reg; }
>
> What is the meaning of static here? Does it specify
> a storage duration or a linkage?
Just to be a little bit more concrete with this question:
According to [dcl.stc]/1 we have:
"[..] A storage-class-specifier shall not be specified in an
explicit specialization (14.7.3) or an explicit instantiation
(14.7.2) directive."
which direcly forbids your construction.
Greetings from Bremen,
Daniel Krügler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
-
Re: Forcing instantiation of a static member of a template
On Mon, 29 Oct 2007 02:28:58 +0100, Daniel Krügler
<daniel.kruegler@googlemail.com> wrote:
> On 28 Okt., 02:11, Jiri Palecek <jpale...@web.de> wrote:
>> Daniel Krügler wrote:
> Consider your syntactic construct again:
>
> template <class T>
> A<T>::A() { template static const A<T>::Reg A<T>::reg; }
>
> What is the meaning of static here? Does it specify
> a storage duration or a linkage? Further-on I see
> nothing in the definition of this entity that is
> related to an instantiation. In contrast, we are still
> in a dependent context here.
OK, static is an error here. But you should note that I'm not writing
syntatctic constructs for pleasure, but I am trying to achieve a goal
(which was stated at the beginning). Disputes about keywords do not really
help.
>> From this follows another difficulty: Which meaning had
> your construction, if I provide an explicit specialization
> for A<T>::A() given some replacement for T, e.g.
>
> template<> A<int>::A(){}
>
> ?
What would you expect? It just wouldn't instantiate the static member.
Nothing in C++ can prevent anyone to specialize a template and break code
by that, so this isn't a real difficulty.
>> > The compiler writers are correct, and the standard hastens to add the
>> > following in [temp.explicit]/5:
>>
>> > "[..] An explicit instantiation for a member of a class template is
>> > placed
>> > in the namespace where the enclosing class template is defined.[..]"
>>
>> Sorry, but I think this clause only states that wherever you
>> instantiate,
>> the instantiation will be created in the namespace enclosing the
>> definition. The example for this clause shows instantiating a class a
>> different namespace, which would not make sense if it were prohibited by
>> the same clause.
>
> I don't share your interpretation, and it seems that the
> committee interprets it quite closely to mine in
>
> http://www.open-std.org/jtc1/sc22/wg...efects.html#44
>
> "All uses of the phrase "in the namespace" in the IS mean "directly
> in the namespace," not in a scope nested within the namespace."
Sorry, but you have completely misunderstood. If you say "xxx is placed in
namespace yyy", interpret it as "xxx shall be placed in namespace yyy" but
then show that it is legal to place xxx in namespace zzz, then I don't see
any logic in this. Whether "in the namespace" means directly or whatever
doesn't matter.
But it is true that this issue is already handled by
http://www.open-std.org/jtc1/sc22/wg...fects.html#275
[ reinserted deleted context ]
>>> Your attempt to provide an explicit instantiation in a function scope
>>> is not supported - and what do you want to you realize with this?
>> I want the thing I mentioned in the very beginning, to instantiate a
>> member
>> of a class template whenever other member, or the whole template, was
>> instantiated.
>
> As shown above I can't see any valid explicit instantiation here.
Again, if you asked what I WANT to do (and then slyly deleted the
question) then it is irrelevant what you can or can't see. The question is
whether you are able to, or willing to help.
Regards
Jiri Palecek
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
-
Fwd: Re: Forcing instantiation of a static member of a template
On Mon, 29 Oct 2007 02:28:58 +0100, Daniel Krügler
<daniel.kruegler@googlemail.com> wrote:
> On 28 Okt., 02:11, Jiri Palecek <jpale...@web.de> wrote:
>> Daniel Krügler wrote:
> Consider your syntactic construct again:
>
> template <class T>
> A<T>::A() { template static const A<T>::Reg A<T>::reg; }
>
> What is the meaning of static here? Does it specify
> a storage duration or a linkage? Further-on I see
> nothing in the definition of this entity that is
> related to an instantiation. In contrast, we are still
> in a dependent context here.
OK, static is an error here. But you should note that I'm not writing
syntatctic constructs for pleasure, but I am trying to achieve a goal
(which was stated at the beginning). Disputes about keywords do not really
help.
>> From this follows another difficulty: Which meaning had
> your construction, if I provide an explicit specialization
> for A<T>::A() given some replacement for T, e.g.
>
> template<> A<int>::A(){}
>
> ?
What would you expect? It just wouldn't instantiate the static member.
Nothing in C++ can prevent anyone to specialize a template and break code
by that, so this isn't a real difficulty.
>> > The compiler writers are correct, and the standard hastens to add the
>> > following in [temp.explicit]/5:
>>
>> > "[..] An explicit instantiation for a member of a class template is
>> > placed
>> > in the namespace where the enclosing class template is defined.[..]"
>>
>> Sorry, but I think this clause only states that wherever you
>> instantiate,
>> the instantiation will be created in the namespace enclosing the
>> definition. The example for this clause shows instantiating a class a
>> different namespace, which would not make sense if it were prohibited by
>> the same clause.
>
> I don't share your interpretation, and it seems that the
> committee interprets it quite closely to mine in
>
> http://www.open-std.org/jtc1/sc22/wg...efects.html#44
>
> "All uses of the phrase "in the namespace" in the IS mean "directly
> in the namespace," not in a scope nested within the namespace."
Sorry, but you have completely misunderstood. If you say "xxx is placed in
namespace yyy", interpret it as "xxx shall be placed in namespace yyy" but
then show that it is legal to place xxx in namespace zzz, then I don't see
any logic in this. Whether "in the namespace" means directly or whatever
doesn't matter.
But it is true that this issue is already handled by
http://www.open-std.org/jtc1/sc22/wg...fects.html#275
[ reinserted deleted context ]
>>> Your attempt to provide an explicit instantiation in a function scope
>>> is not supported - and what do you want to you realize with this?
>> I want the thing I mentioned in the very beginning, to instantiate a
>> member
>> of a class template whenever other member, or the whole template, was
>> instantiated.
>
> As shown above I can't see any valid explicit instantiation here.
Again, if you ask what I WANT to do (and then slyly delete the question)
then it is irrelevant what you can or can't see. The question is whether
you are able to, or willing to help.
Regards
Jiri Palecek
--
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Similar Threads
-
By Application Development in forum c++
Replies: 3
Last Post: 12-05-2007, 07:39 AM
-
By Application Development in forum c++
Replies: 7
Last Post: 11-01-2007, 04:28 PM
-
By Application Development in forum c++
Replies: 14
Last Post: 10-17-2007, 04:38 AM
-
By Application Development in forum c++
Replies: 20
Last Post: 07-27-2007, 07:45 AM
-
By Application Development in forum c++
Replies: 3
Last Post: 05-01-2007, 02:45 PM