Search code examples
c++templateslanguage-lawyerusing-declarationinheriting-constructors

In using-declaration, can dependent names render to constructors after template substitution?


In this example:

template<class T>
struct S : T
{
    using T::X;
};

T::X is a dependent name that refers to the member X in T. If S<T> is instantiated with T = X:

struct X
{
    X(int) {}
};
...
S<X> s(42);

Will the using-declaration become inheriting-constructor?

Clang rejects the code DEMO, while g++ accepts it.

Note that if we write:

using T::X::X;

Both compilers accept the code and treat it as inheriting-constructor. Is using T::X allowed to become inheriting-constructor by standard?


Solution

  • Thanks to T.C. for pointing this out:

    Core issue 2070, which is in the drafting stage (it's confirmed to be a problem, and the wording of the solution is being worked on), deals with this case. The proposed fix is requiring both IDs to be the same ID in order for this code to be accepted as an inheriting constructor.

    In this light, the error message from clang makes sense, as T::X would be the type X, which triggers the "type from template without typename tag" error.

    Original Post:

    So it seems to me that the real question is, "Is it allowable that a template instantiation changes the semantic meaning of a using statement?"

    And the answer is, it is not disallowed. I do not know if this interaction was foreseen and intended by the authors of the standard. But as far as I can see, referencing both the using declaration in Section 10 and the template initialization in Section 17, by the letter of the standard, yes, using T::X is allowed and yes, the using declaration will become an inheriting constructor when T is X.