Reputation: 1288
I'm trying to do the following: I have a class and whenever I declare a new instance of this class I want to set a static variable in another class. I'm trying to do it with templates so I can do something like class C : public D<AA, BB, CC, DD>
(using variadic parameters). The problem is that the static variable of the classes AA, BB, CC, DD
(all which share the same base) is protected. So I'm trying make C
a friend of the classes so it can access the variable.
What I tried is this:
template <class T>
class Foo
{
protected:
static T* t;
friend T;
};
template <class T>
T* Foo<T>::t = nullptr;
First I declared the base class Foo, which has the static variable and the friend declaration. This is meant to be inherited by other classes.
Then I made this:
template <class Self, class T> //T = Type derived from Foo
struct Bar
{
Bar()
{
T::t = static_cast<Self*>(this);
}
};
Which is the class that when instantiated will set the static variable in the type T
.
And this is the final implementation:
struct FooDerived;
struct BarDerived : public Bar<BarDerived, FooDerived>
{
};
struct FooDerived : public Foo<BarDerived>
{
};
My idea is that:
BarDerived
will set the static t
in FooDerived
FooDerived
inherits Foo<BarDerived>
which is a friend of BarDerived
BarDerived
is a friend of Foo<BarDerived>
, it can access Foo<BarDerived>::t
But that doesn't work and I get the following compile error:
prog.cpp: In instantiation of ‘void Bar<Self, T>::test() [with Self = BarDerived; T = FooDerived]’:
prog.cpp:37:9: required from here
prog.cpp:11:4: error: ‘BarDerived* Foo<BarDerived>::t’ is protected
T* Foo<T>::t = nullptr;
^
prog.cpp:18:8: error: within this context
T::t = static_cast<Self*>(this);
^
Did I miss something with the way I expected the templates/friendship to behave?
Upvotes: 0
Views: 60
Reputation: 217775
You may use the following: https://ideone.com/RW3xfV
template <class T>
class Foo
{
protected:
static T* t;
template <class Self, class U> //T = Type derived from Foo
friend struct Bar;
};
as it is Bar
which requires access to Foo<T>::t
.
Upvotes: 1