During the discussion came to this program:
#include <iostream> using namespace std; class A { protected: int var; public: A(int x) { var = x; // Это обращение к A::var } }; class B: public A { protected: int var; public: B():A(2) { var = 4; // Обращение к B::var } }; class C: public A { protected: int var; public: C():A(3) { var = 6; // Обращение к C::var } }; class D: public B, public C { protected: int var; public: void method() { var = B::A::var; // Должен выдать 2 cout << var << endl; var = C::A::var; // Должен выдать 3 cout << var << endl; var = B::var; // Должен выдать 4 cout << var << endl; var = C::var; // Должен выдать 6 cout << var << endl; } }; int main() { D obj; obj.method(); } The program compiles perfectly and displays what was expected in Visual C ++ 2015. Attempting to compile with the help of GCC on ideone.com gives a lot of errors:
prog.cpp: In member function 'void D::method()': prog.cpp:46:21: error: 'A' is an ambiguous base of 'D' var = B::A::var; // Должен выдать 2 ^ prog.cpp:49:21: error: 'A' is an ambiguous base of 'D' var = C::A::var; // Должен выдать 3 ^ The question for experts on the standard is who is wrong here and who is right? If VC ++ is wrong, then what, why, and how to do it right ?
Update 10/22/2016
Perhaps the most portable is not to rely on the name lookup, but to use transformations in the spirit of
var = static_cast<A*>(static_cast<B*>(this))->var; var = ((A*)(C*)this)->var; But at the same time, you need to make a var in public . (Again, I don’t understand why and where this reference is in the standard ...) The full code here is http://ideone.com/wt9yrz