Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Destructor defined through a type alias

This code

struct Inner{
    Inner();
    ~Inner();
};

struct Outer {
    using Inner = ::Inner;
};

Outer::Inner::Inner()
{
    //
}

Outer::Inner::~Inner()
{
    //
}

is compiled by GCC up to the latest as of today (14.2) but is rejected by clang since version 11 (accepted by clang 10).

It's strange (to me) that only the destructor is rejected.

Which compiler is right? Can somebody cite chapter and verse from the standard?

like image 337
Bulletmagnet Avatar asked Oct 29 '25 10:10

Bulletmagnet


1 Answers

Per C++23 DIS [basic.lookup.qual.general]/41:

If a qualified name Q follows a ~: … its nested-name-specifier N shall nominate a type. If N has another nested-name-specifier S, Q is looked up as if its lookup context were that nominated by S.

Inner after ~ in Outer::Inner::~Inner is looked up in Outer, which finds type alias. But per [class.dtor]/1, destructor declaration shall use injected-class-name after ~:

its declarator shall be a function declarator … where … the id-expression has one of the following forms … nested-name-specifier ~class-name and the class-name is the injected-class-name of the class nominated by the nested-name-specifier


P.S. Without preceding ~, the lookup is performed as usual, in the context associated with nested-name-specifier N. So, in the constructor declaration, the second Inner is looked up in the context nominated by Outer::Inner, which is the class scope of struct Inner, finds injected-class-name, and the constructor declaration is valid


  1. Pre-P1787 rule sounded as

in a qualified-id of the form:

nested-name-specifieropt class-name :: ~ class-name

the second class-name is looked up in the same scope as the first

like image 173
Language Lawyer Avatar answered Oct 30 '25 23:10

Language Lawyer