Skip to content

[temp.res.general] p5: dependent qualified-id and using-declarator #4791

Description

@xmh0511

In the current draft, [basic.lookup.qual#general-2] specifies the qualified name, where it seems that it intends to use qualified-id to cover such as a simple-type-specifier that has the form nested-name-specifieropttype-name. In other words, they all can form nested-name-specifier identifier on syntax. However, they are not the same thing on grammar.

Furthermore, [temp.res#general-5] also intends to use qualified-id to cover a simple-type-specifier that may have the aforementioned form. The meaning of the qualified-id is vague in such use, consider a using-declarator, which has the form nested-name-specifier unqualified-id

using T::identifier;

Does that mean any rule that uses the qualified-id to cover the form that is not a qualified-id on grammar can also impose on the using-declarator that has the same form? It seems a defect in the current standard. This issue is also mentioned on SO.

This example would illustrate the vague

struct X{
    typedef int Type;
};
template<typename T>
struct Test:T{
    using T::Type;  // #1
};
int main(){
   Test<X> obj;
}

GCC agrees on this example while Clang reports an error. If we say the using-declarator at #1 is considered as a qualified-id, then Clang is right due to [temp.res#general-5] imposes on it.

A qualified-id whose terminal name is dependent and that is in a type-only context is considered to denote a type.

I don't think it's a good example here, I still think Clang is wrong, even if T::Type is not considered to denote a type, I didn't see any big deal at #1. This issue intends to expose that the extra given meaning to qualified-id would make its meaning be a mess in some rules that mention qualified-id.

Activity

  1. changed the title [-]The qualified-id has exceeded its designated extent in the intent of certain rules[/-] [+]The qualified-id has exceeded its grammar meaning in the intent of certain rules[/+] on Aug 4, 2021
  2. jensmaurer commented on Aug 4, 2021

    @jensmaurer
    Member

    First of all, a qualified name as defined in [basic.lookup.qual.general] is very much different from a qualified-id, and intentionally so.

    Second, [temp.res.general] p5 expressly uses qualified-id and in the next sentence discusses using-declarator; applying an "if and only if" clarification to the second sentence in p5 fixes that issue without messing with qualified-id.

    @opensdh, any thoughts here?

  3. changed the title [-]The qualified-id has exceeded its grammar meaning in the intent of certain rules[/-] [+][temp.res.general] p5: dependent using-declaratorThe qualified-id has exceeded its grammar meaning in the intent of certain rules[/+] on Aug 4, 2021
  4. changed the title [-][temp.res.general] p5: dependent using-declaratorThe qualified-id has exceeded its grammar meaning in the intent of certain rules[/-] [+][temp.res.general] p5: dependent using-declarator[/+] on Aug 4, 2021
  5. xmh0511 commented on Aug 4, 2021

    @xmh0511
    ContributorAuthor

    Consider this example

    struct Test{
      typedef int type;
    };
    Test::type a = 0; //#1

    Is the terminal name in Test::type called a qualified name? I think it should be a qualified name, however, we cannot find simple-type-specifier in the list of [basic.lookup.qual#general-2]. Presumably, the rule intends to category the simple-type-specifier into qualified-id, otherwise, it cannot be interpreted. On grammar, a simple-type-specifier is not a qualified-id. @opensdh has confirmed this issue and said it could be considered a defect, please see this comment.

  6. jensmaurer commented on Aug 4, 2021

    @jensmaurer
    Member

    I'm certainly not going to address any specification ambiguities of a qualified-id vs. a simple-type-specifier vs. a using-declarator etc. in an editorial issue.

    However, it seems plausible to add simple-type-specifier to the list in [basic.lookup.qual.general] p2.

  7. xmh0511 commented on Aug 4, 2021

    @xmh0511
    ContributorAuthor

    @jensmaurer Agree. I also think the first sentence in [temp.res#general-5] should also avoid using qualified-id. Consider this example

    template<class T>
    struct C{
     T::type member_;
    };

    T::type is the decl-specifier of the member-declaration as said in [temp.res#general-4]. In the grammar tree of decl-specifier, it is impossible to be a qualified-id, however [temp.res#general-5] intends to use qualified-id to cover the simple-type-specifier(T::type). I think we could use "qualified name" to replace the qualified-id in the first sentence in [temp.res#general-5].

  8. jensmaurer commented on Aug 4, 2021

    @jensmaurer
    Member

    No, type is the qualified name here, not T::type, so this would be saying something different.

    I think this is the operative paragraph where we differentiate between qualified-id and simple-type-specifier in a dependent context. I think it's too early to talk about either here, and we should simply talk about the grammatical form nested-name-specifier :: identifier and its disambiguation here.

  9. jensmaurer commented on Aug 4, 2021

    @jensmaurer
    Member

    If we already know we have a simple-type-specifier (because that's the only possibility per the grammar), we don't need temp.res.general p5 to tell us we're dealing with a type. It's only in the case where the general grammar rules would allow parsing as a qualified-id that we need the type-only context rules.

  10. xmh0511 commented on Aug 5, 2021

    @xmh0511
    ContributorAuthor

    I think this is the operative paragraph where we differentiate between qualified-id and simple-type-specifier in a dependent context. I think it's too early to talk about either here,

    Violent agree! qualified-id can only appear as an expression, if we directly say it's a qualified-id, it has already meant it's an expression rather than anything others. The ambiguous case is

    typename T::type * id;

    T::type could be either a qualified-id or a type-specifier. However, we cannot arbitrarily say it's just a qualified-id and try to use [temp.res#general-5] to state it's considered to denote a type. It's contradictory.

    In addition, I think the grammar nested-name-specifier :: identifier is not sufficient to list all possible components, such as T::type<template-argument-list>.

  11. jensmaurer commented on Aug 5, 2021

    @jensmaurer
    Member

    No, typename T::type is exactly not ambiguous (because it's a typename-specifier). Without typename, it's ambiguous, though.

  12. xmh0511 commented on Aug 5, 2021

    @xmh0511
    ContributorAuthor

    That has enforced the subject of this issue. Since the component whose terminal name is in type-only context is one of them: typename-specifier, nested-name-specifier, elaborated-type-specifier, class-or-decltype, type-specifier, decl-specifier. How could these components be a qualified-id?

  13. xmh0511 commented on Aug 5, 2021

    @xmh0511
    ContributorAuthor
    T::type * id;

    We could say T::type may be a qualified-id or a simple-type-specifier(it's ambiguous in this context). If its terminal name is in a type-only context, we say T::type is interpreted as a simple-type-specifier; otherwise, it's... However, if we say it's a qualified-id at the beginning, we have already designated it's just an expression, an expression can never be a type as per [expr.prim.id.qual#5].

    I cannot figure out a simple way that can avoid use qualified-id but can mention all the grammars whose forms look like the qualified-id. Could we say

    A potential qualified-id whose terminal name...

    To emphasize that it's not necessary to be a qualified-id eventually?

  14. jensmaurer commented on Aug 5, 2021

    @jensmaurer
    Member

    I think we only need to discuss the two forms "nested-name-specifier identifier" and "nested-name-specifier template(opt) simple-type-id". Everything else is already unambiguous between simple-type-specifier and qualified-id.

  15. changed the title [-][temp.res.general] p5: dependent using-declarator[/-] [+][temp.res.general] p5: dependent qualified-id and using-declarator[/+] on Aug 5, 2021
  16. self-assigned this
    on Aug 5, 2021
  17. opensdh commented on Aug 31, 2021

    @opensdh
    Contributor

    For the record, I don't have anything to add here beyond what we said in the CWG review, which was itself not a complete answer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions