Here is the (simplified) base class:
template <class T>
class SharedObject
{
protected:
QExplicitlySharedDataPointer <typename T::Data> d;
};
And here is the derived:
class ThisWontCompile : public SharedObject <ThisWontCompile>
{
private:
friend class SharedObject;
struct Data : public QSharedData
{
int id;
};
};
Is there any workaround to access ThisWontCompile::Data from SharedObject? What exactly can and what exactly cannot be done with the derived object from the base object?
This actually isn't related to the accessibility and friendship, it's related to the use of CRTP. Consider the following example that also exhibits the problem:
template <class T>
struct Base
{
typedef typename T::Data Data;
};
struct ThisWontCompile : public Base<ThisWontCompile>
{
struct Data { };
};
The problem is that ThisWontCompile
is incomplete at the time it is used as a template argument to Base
, so it can only be used as an incomplete type in Base
.
For a handful of solutions to your specific problem, consult the answers to this other question, especially Martin's recommendation to use a traits class, which would basically look like this:
// Base
template <typename T>
struct BaseTraits;
template <typename T>
struct Base
{
typedef typename BaseTraits<T>::Data Data;
};
// Derived
struct Derived;
template <>
struct BaseTraits<Derived>
{
struct Data { };
};
struct Derived : public Base<Derived>
{
};
typename BaseTraits<Derived>::Data
can be used in both Derived
and in Base
. If Derived
is itself a template, you can use a partial specialization for the traits class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With