I have a class template containing an inner class. I want the outer class to be the only one able to construct objects of the inner class but I need to expose the inner class to the outside so others can call a public method of its own.
Outer also defines a public interface for callback actions, in which it is supposed to provide an object of type Inner to the callee. So Outer must construct an Inner object and pass it as parameter in the callback method.
For example:
template<typename T>
class Outer {
public:
virtual void callbackMethod(std::shared_ptr<Outer<T>::Inner> inner) = 0;
class Inner {
private:
Obj obj;
Inner(...) {} // init obj, a private member of another type
std::shared_ptr<Inner> createInner() {
std::shared_ptr<Inner> inner = std::make_shared<Inner>(...);
... /* do some work */ ...
return inner;
}
public:
~Inner=default();
void exposedMethod() {
...
}
}
}
Under certain conditions, Outer creates an Inner object and calls the callback method, which is supposed to be implemented by someone else. The callee should then be able to do something like this:
inner->exposedMethod();
Of course, the idea is not letting outsiders to be able to construct Inner objects; this is why I designed Inner as a nested class and declared its constructor and creator methods as private.
My problem is that I need my Outer class to call createInner but the compiler complains about Outer trying to access private Inner constructor. I tried to declare Outer as friend inside Inner, but the error is still there:
class Inner {
friend class Outer<T>;
...
}
I have read that friendship follows other rules when applied to class templates. I am using clang with C++17.
So the question is, how could I design my classes so that class Outer can be the only one allowed to create objects of Inner type, it but at the same time be able to expose one of its methods to the outside? Please remember that Outer is a class template.
By the way, I don't care if the solution requires Inner to be a first-level class.
Thanks a lot.