First of all, sorry for the length title. I encountered a weird issue where, the existence of a private base of the same type as a member shaddows access to the member in a child class but not outside the child class definition. Look at the following code:
struct PrivateBase {};
struct Base : private PrivateBase {
// Member accessors.
PrivateBase* GetPrivateBase() { return &a; }
template<typename T>
T* GetPrivateBase() { return &a; }
// Free function accessors.
friend PrivateBase* FreeGetPrivateBase(Base* b) { return &(b->a); }
template<typename T>
friend T* FreeGetPrivateBase(Base* b);
private:
// This member has nothing to do with the PrivateBase base class.
PrivateBase a;
};
template<typename T>
T* FreeGetPrivateBase(Base* b) { return &(b->a); }
struct Child : public Base {
void SomeFunc() {
// Works!1!!.
GetPrivateBase();
// Doesn't work.
//GetPrivateBase<PrivateBase>(); // (1)
// Works!1!!.
FreeGetPrivateBase(this);
// Doesn't work.
//FreeGetPrivateBase<PrivateBase>(this);
}
};
int main() {
Child c;
// Works!1!!.
c.GetPrivateBase<PrivateBase>();
// Works!1!!.
FreeGetPrivateBase<PrivateBase>(&c);
return 0;
}
I've tried to compile this both, with g++-4.8.4 and clang++-3.7.1. With clang and (1) uncommented I get:
minimal.cc:30:20: error: 'PrivateBase' is a private member of 'PrivateBase'
GetPrivateBase<PrivateBase>();
^
minimal.cc:3:15: note: constrained by private inheritance here
struct Base : private PrivateBase {
^~~~~~~~~~~~~~~~~~~
minimal.cc:1:8: note: member is declared here
struct PrivateBase {};
^
The fun fact is that access to a works outside of Child and inside Child with the non-templated accessors. It also works inside Child with the templated accessors if I get rid of the private base class. I would love to blame it on the compiler but unconventionally enough both contenders seem to agree. Could anybody explain the interplay between templated accessors, child scope and private base class? - Thanks.
Aucun commentaire:
Enregistrer un commentaire