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> ...

+ Reply to Thread
Results 1 to 6 of 6

Re: Forcing instantiation of a static member of a template

  1. Default 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() { &reg; }
    >
    > 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! ]


  2. Default 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() { &reg; }
    >>
    >> 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! ]


  3. Default 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! ]


  4. Default 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! ]


  5. Default 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! ]


  6. Default 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! ]


+ Reply to Thread

Similar Threads

  1. Can a static member function access non-static member?
    By Application Development in forum c++
    Replies: 3
    Last Post: 12-05-2007, 07:39 AM
  2. Static local variable in an inline static member function
    By Application Development in forum c++
    Replies: 7
    Last Post: 11-01-2007, 04:28 PM
  3. Static Member Function Template Specialization
    By Application Development in forum c++
    Replies: 14
    Last Post: 10-17-2007, 04:38 AM
  4. Template static member initialization
    By Application Development in forum c++
    Replies: 20
    Last Post: 07-27-2007, 07:45 AM
  5. On template instantiation
    By Application Development in forum c++
    Replies: 3
    Last Post: 05-01-2007, 02:45 PM