Date
2012-09-15.00:00:00
Message id
4188

Content

Additional notes (September, 2012):

Tomasz KamiƄski pointed out three additional motivating examples:

  struct Very_base { int a; };
  struct Base1 : Very_base {};
  struct Base2 : Very_base {};
  struct Derived : Base1, Base2 {}

  int main() {
    Derived d;
    int Derived:: * a_ptr = &Derived::Base1::a; //error: Very_base ambiguous despite qualification
  };

Also:

  struct Base { int a; };
  struct Derived : Base { int b; };

  template<typename Class, typename Member_type, Member_type Base:: * ptr>
  Member_type get(Class &c) { return c.*ptr; }

  void call(int (*f)(Derived &));

  int main() {
    call(&get<Derived, int, &Derived::b>); // Works correctly
    call(&get<Derived, int, &Derived::a>); // Fails because &Derived::a returns an int Base::*
                                           // and no conversions are applied to pointer to member
                                           // (as specified in 13.4.3 [temp.arg.nontype] paragraph 5)
    call(&get<Base, int, &Derived::a>);    //Template function is instantiated properly but has invalid type
  }

Finally:

  struct Base { int a; };
  struct Derived : private Base {
  public:
    using Base::a; //make a accessible
  };

  int main() {
    Derived d;
    d.a; // valid
    int Derived::* ptr = &Derived::a; // Conversion from int Base::* to int Derived::*
                                      // is ill-formed because the base class is inaccessible
  }