c++language-lawyerusingusing-declaration

Can you use using to redeclare a public member in base class as private in derived class?


This code snippet demonstrating changing class member access came from IBM.

struct A {
protected:
  int y;
public:
  int z;
};

struct B : private A { };

struct C : private A {
public:
  using A::y;
  using A::z;
};

struct D : private A {
protected:
  using A::y;
  using A::z;
};

struct E : D {
  void f() {
    y = 1;
    z = 2;
  }
};

struct F : A {
public:
  using A::y;
private:
  using A::z;
};

int main() {
  B obj_B;
//  obj_B.y = 3;
//  obj_B.z = 4;

  C obj_C;
  obj_C.y = 5;
  obj_C.z = 6;

  D obj_D;
//  obj_D.y = 7;
//  obj_D.z = 8;

  F obj_F;
  obj_F.y = 9;
  obj_F.z = 10;
}

According to the article, modifying obj_F.z is allowed because the using declaration in the F class does not take effect, and therefore, F::z is still public.

However, when I plug this into Compiler Explorer, it does not compile, saying F::z is private. What's going on here?


Solution

  • The article seems wrong. It says,

    You cannot restrict the access to x with a using declaration.

    But I can't find such statement from the standard. [namespace.udecl]/19

    A synonym created by a using-declaration has the usual accessibility for a member-declaration.

    [ Example:

    class A {
    private:
        void f(char);
    public:
        void f(int);
    protected:
        void g();
    };
    
    class B : public A {
      using A::f;       // error: A​::​f(char) is inaccessible
    public:
      using A::g;       // B​::​g is a public synonym for A​::​g
    };
    

    — end example ]

    Even the example is increasing the accessibility, but the standard doesn't say accessibility can't be restricted.

    PS: Both clang and gcc fail to compile the code.