Problem
Here's a contrived example of a problem I'm facing. I have a templated object with a map
function that creates a new object and operates on private (or protected, it doesn't matter) members within that new object.
template<typename T>
class Foo {
public:
template<typename R>
Foo<R> map(std::function<R(std::optional<T>)> &&function) {
auto mappedValue = function(mValue);
Foo<R> f{};
f.mValue = mappedValue;
}
private:
std::optional<T> mValue;
};
This works fine so long as T
and R
are identical. For example:
int main()
{
Foo<int> f1{};
Foo<int> f2 = f1.map<int>([](std::optional<int> value) {
if (value.has_value()) {
return value.value() + 1;
}
else {
return 1;
}
});
return 0;
}
However, the moment I T
!= R
, I run into problems:
int main()
{
Foo<int> f1{};
Foo<double> f2 = f1.map<double>([](std::optional<int> value) {
if (value.has_value()) {
return value.value() + 1.0;
}
else {
return 1.0;
}
});
return 0;
}
main.cpp:22:11: error: ‘std::optional Foo::mValue’ is private within this context
f.mValue = mappedValue;
~~^~~~~~
main.cpp:26:22: note: declared private here
std::optional<T> mValue;
^~~~~~
Question
This is easily understood. C++ access control works on a per-class basis and Foo<int>
is not the same class as Foo<double>
. I can even fix the problem by adding: friend class Foo<int>
. That doesn't scale well, since I don't know what T
and R
may be.
Does anyone know of a generic way to handle this problem and give Foo<int>
access to Foo<double>
's private/protected members?