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

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

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

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

    Root Relative Path Injected as String Variable

    Jordan Richard, May 2, 2005, in forum: ASP .Net
    Replies:
    2
    Views:
    3,350
    Brock Allen
    May 2, 2005
  2. christopher diggins
    Replies:
    16
    Views:
    730
    Pete Becker
    May 4, 2005
  3. kingflux
    Replies:
    3
    Views:
    374
    kingflux
    Dec 21, 2006
  4. anon
    Replies:
    4
    Views:
    351
  5. Unwanted data injected into datagrid textbox

    , Nov 10, 2006, in forum: ASP .Net Datagrid Control
    Replies:
    0
    Views:
    679
Loading...

Share This Page