Proposal: Allow using injected class name when template name is in scope

Discussion in 'C++' started by Johannes Schaub (litb), Sep 10, 2010.

  1. The following is not currently well-formed:

    template<typename>
    struct base { void f() { } };

    struct A : base<int> {
    void f(int) { }
    };

    int main() {
    A a;
    a.base::f();
    }

    It would seem to be beneficial to make this work by finding the inherited
    injected class name of base<int> in A. But currently it is ill-formed
    because that name does not denote the same entity as the name found in the
    context of the entire postfix-expression, which refers to the base template.

    To make this work, could one not get rid of the part of 3.4.3/1 that says
    "... and templates whose specializations are types."? When is a class-
    template name or a template alias name ever going to be valid before a "::"?
    So if this part would be removed, the global base template would be ignored,
    and only the injected class name in A would be found and the program would
    be valid.
     
    Johannes Schaub (litb), Sep 10, 2010
    #1
    1. Advertisements

  2. Re: Proposal: Allow using injected class name when template nameis in scope

    On 9/10/2010 1:15 PM, Johannes Schaub (litb) wrote:
    > The following is not currently well-formed:
    >
    > template<typename>
    > struct base { void f() { } };
    >
    > struct A : base<int> {
    > void f(int) { }
    > };
    >
    > int main() {
    > A a;
    > a.base::f();
    > }
    >
    > It would seem to be beneficial to make this work by finding the inherited
    > injected class name of base<int> in A. But currently it is ill-formed
    > because that name does not denote the same entity as the name found in the
    > context of the entire postfix-expression, which refers to the base template.
    >
    > To make this work, could one not get rid of the part of 3.4.3/1 that says
    > "... and templates whose specializations are types."? When is a class-
    > template name or a template alias name ever going to be valid before a "::"?
    > So if this part would be removed, the global base template would be ignored,
    > and only the injected class name in A would be found and the program would
    > be valid.


    What problem does it solve that cannot be solved using some other ways?

    In your case, try adding a 'using' declaration in 'A':

    struct A : base<int> {
    void f(int) {}
    using base<int>::f;
    };

    and then omit 'base::' in the call...

    V
    --
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Sep 10, 2010
    #2
    1. Advertisements

  3. Victor Bazarov wrote:

    > On 9/10/2010 1:15 PM, Johannes Schaub (litb) wrote:
    >> The following is not currently well-formed:
    >>
    >> template<typename>
    >> struct base { void f() { } };
    >>
    >> struct A : base<int> {
    >> void f(int) { }
    >> };
    >>
    >> int main() {
    >> A a;
    >> a.base::f();
    >> }
    >>
    >> It would seem to be beneficial to make this work by finding the inherited
    >> injected class name of base<int> in A. But currently it is ill-formed
    >> because that name does not denote the same entity as the name found in
    >> the context of the entire postfix-expression, which refers to the base
    >> template.
    >>
    >> To make this work, could one not get rid of the part of 3.4.3/1 that says
    >> "... and templates whose specializations are types."? When is a class-
    >> template name or a template alias name ever going to be valid before a
    >> "::"? So if this part would be removed, the global base template would be
    >> ignored, and only the injected class name in A would be found and the
    >> program would be valid.

    >
    > What problem does it solve that cannot be solved using some other ways?
    >
    > In your case, try adding a 'using' declaration in 'A':
    >
    > struct A : base<int> {
    > void f(int) {}
    > using base<int>::f;
    > };
    >
    > and then omit 'base::' in the call...
    >


    It just seems intuitive to me if it worked. Because if you place the "base"
    template in a non-global namespace, it suddenly works because "base" is then
    not found by unqualified lookup anymore. Such a difference causes confusion
    I think.
     
    Johannes Schaub (litb), Sep 10, 2010
    #3
  4. Re: Proposal: Allow using injected class name when template nameis in scope

    On 9/10/2010 1:24 PM, Johannes Schaub (litb) wrote:
    > Victor Bazarov wrote:
    >
    >> On 9/10/2010 1:15 PM, Johannes Schaub (litb) wrote:
    >>> The following is not currently well-formed:
    >>>
    >>> template<typename>
    >>> struct base { void f() { } };
    >>>
    >>> struct A : base<int> {
    >>> void f(int) { }
    >>> };
    >>>
    >>> int main() {
    >>> A a;
    >>> a.base::f();
    >>> }
    >>>
    >>> It would seem to be beneficial to make this work by finding the inherited
    >>> injected class name of base<int> in A. But currently it is ill-formed
    >>> because that name does not denote the same entity as the name found in
    >>> the context of the entire postfix-expression, which refers to the base
    >>> template.
    >>>
    >>> To make this work, could one not get rid of the part of 3.4.3/1 that says
    >>> "... and templates whose specializations are types."? When is a class-
    >>> template name or a template alias name ever going to be valid before a
    >>> "::"? So if this part would be removed, the global base template would be
    >>> ignored, and only the injected class name in A would be found and the
    >>> program would be valid.

    >>
    >> What problem does it solve that cannot be solved using some other ways?
    >>
    >> In your case, try adding a 'using' declaration in 'A':
    >>
    >> struct A : base<int> {
    >> void f(int) {}
    >> using base<int>::f;
    >> };
    >>
    >> and then omit 'base::' in the call...
    >>

    >
    > It just seems intuitive to me if it worked. Because if you place the "base"
    > template in a non-global namespace, it suddenly works because "base" is then
    > not found by unqualified lookup anymore. Such a difference causes confusion
    > I think.


    After I posted my reply I thought a bit, and this occurred to me: 'base'
    is not a member/base name, is it? 'base<int>' would be, no? I can't
    claim full understanding of the lookup rules in the current Standard,
    and even less in the upcoming one...

    V
    --
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Sep 10, 2010
    #4
    1. Advertisements

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Paul Opal
    Replies:
    12
    Views:
    1,210
    Paul Opal
    Oct 11, 2004
  2. Jonathan Bartlett
    Replies:
    3
    Views:
    547
  3. christopher diggins
    Replies:
    16
    Views:
    1,041
    Pete Becker
    May 4, 2005
  4. AndrewD
    Replies:
    4
    Views:
    664
    AndrewD
    Jan 26, 2007
  5. A L
    Replies:
    1
    Views:
    696
    Alf P. Steinbach /Usenet
    Aug 25, 2010
  6. Alia Khouri
    Replies:
    8
    Views:
    441
    Neil Cerutti
    Apr 5, 2011
  7. Wolfgang Nádasi-Donner
    Replies:
    1
    Views:
    177
    Wolfgang Nádasi-Donner
    May 15, 2007
  8. Yakov
    Replies:
    1
    Views:
    215
    John W. Krahn
    Nov 12, 2006
Loading...