问题
这是我面临的一个问题的一个人为的例子。我有一个带有map
函数的模板化对象,它创建了一个新对象,并对该新对象中的私有(或受保护的,这无关紧要(成员进行操作。
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;
};
只要T
和R
相同,这就可以很好地工作。例如:
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;
}
然而,当我T
!=R
,我遇到问题:
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;
^~~~~~
问题
这很容易理解。C++访问控制在每个类的基础上工作,并且Foo<int>
与Foo<double>
不是同一类。我甚至可以通过添加:friend class Foo<int>
来解决这个问题。这并不能很好地扩展,因为我不知道T
和R
可能是什么
有人知道一种通用的方法来处理这个问题并允许Foo<int>
访问Foo<double>
的私有/受保护成员吗?
我想明白了。
您需要将当前类声明为其自身的朋友。
template<typename T>
friend class Foo;
整个事情看起来是这样的:
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;
template<typename T>
friend class Foo;
};