Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

template private inheritance in vc++10 is not accessible

The following code compiles using GCC 4.4.6 and Comeau 4.3.10.

#include <iostream>

struct A { int name; };
template<typename T> struct C : T { using T::name; };
struct B : private A { friend struct C<B>; };

int main()
{
    C<B> o;
    o.name = 0;
}

It gives the following error in VC++10:

main.cpp(4): error C2877: 'A::name' is not accessible from  'A'
main.cpp(10): error C2247: 'A::name' not accessible because 'B' uses 'private' to inherit from 'A'

What's a good cross-compiler workaround that allows o.name = 0;?

Note: Adding using A::name to B takes care of the problem, but publishes the A::name member to everyone, whereas it should only be visible to a particular template instantiation, namely C<B>.

like image 756
Nick Avatar asked Sep 06 '12 06:09

Nick


2 Answers

Work around is what @kerrekSB suggested, add using A::name; in class B:

struct A { int name; };
template<typename T> struct C : T { using T::name; };

struct B : private A { 
using A::name; 
friend struct C<B>;
};

your initial example didn't work cause class A is private to B and class C<B> is friend of B but when you access member name from object of C<B> , line using T::name; creates problem since the class B doesn't has any member name in it. it's scope search which find the member name when you try to access it via object of class B

Edit :

Adding using A::name to B takes care of the problem, but publishes the A::name member to everyone, whereas it should only be visible to a particular template instantiation, namely C

if that's the case , then simply declare statement using A::name; in private section in class B i.e

struct B : private A {
protected: using A::name; 
public:
friend struct C<B>;
};
like image 73
Mr.Anubis Avatar answered Nov 04 '22 21:11

Mr.Anubis


There seems to be a fundamental difference in visibility considerations between gcc and VC++ when using member using-declarations; check this simplified example without templates:

struct A { int name; };
struct B: private A { friend struct C; };
struct C: B {using B::name; };

int main()
{
   C o;
   o.name = 0;
}

It will compile on gcc but not on VC++ (with basically the same error as in the question). Will have to consult the standard on who is doing it right...

like image 35
codeling Avatar answered Nov 04 '22 20:11

codeling