Exposing private base class name with `using` in C++
Asked Answered
G

2

11

In a situation when some struct D inherits another struct A twice: once privately via B and the second time publicly via C, is it allowed to write using B::A in D?

struct A {};
class B : A {};
struct C : A {};
struct D : B, C { 
    using B::A;  //ok in GCC, error in Clang
};

The program is accepted by GCC, but Clang prints the error:

error: 'A' is a private member of 'A'

Demo: https://gcc.godbolt.org/z/5jeqrzorE

using B::A must just expose injected class name A from D. On the one hand, A is already available to use in D (so GCC accepts it), but on the other hand A is private within B (so Clang rejects it). Which one compiler is right here?

Guanase answered 24/9, 2021 at 7:24 Comment(0)
C
1

[class.access.base]/5:

The access to a member is affected by the class in which the member is named. This naming class is the class in whose scope name lookup performed a search that found the member.

The naming class in this case is B. Since A as a member of B is private, it is not accessible in D, making the using-declaration ill-formed.

Corsair answered 9/5, 2023 at 13:3 Comment(0)
O
-1

It would somehow cause ambiguity in this case. The class lookup needs to be ignored when checking A. GCC should be correct since B::A and C::A refer to the same A from D. Even clang could not detect the error if using C::A is added

struct A {};
struct B :  A {};
struct C : A {};
struct D : C, B { 
    using B::A;  //ok in Clang, error in GCC
    using C::A;
};

https://timsong-cpp.github.io/cppwp/namespace.udecl#1

Odlo answered 24/9, 2021 at 11:7 Comment(2)
You replaced class B with struct B in your code. This changes the inheritance type from private to public.Guanase
I just want to show the clang's behavior is not correct in that caseOdlo

© 2022 - 2025 — McMap. All rights reserved.