C++访问控制不适用于模板化对象



问题

这是我面临的一个问题的一个人为的例子。我有一个带有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;
};

只要TR相同,这就可以很好地工作。例如:

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>来解决这个问题。这并不能很好地扩展,因为我不知道TR可能是什么

有人知道一种通用的方法来处理这个问题并允许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;
};

相关内容

最新更新