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

C++ access control not working for templated objects

问题

这是我面临的问题的人为示例。我有一个带有 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++ 访问控制在每个 class 基础上工作,Foo<int> 与 class 与 Foo<double> 不同。我什至可以通过添加:friend class Foo<int> 来解决问题。这不能很好地扩展,因为我不知道 TR 可能是什么。

有谁知道处理此问题并授予 Foo<int> 访问 Foo<double> 的 private/protected 成员的通用方法?

我想通了。

您需要声明您当前的 class 为自己的好友。

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;
};