c++ 如何引用外部类的受保护成员作为类模板的构造函数的默认参数

nwwlzxa7  于 2023-08-09  发布在  其他
关注(0)|答案(1)|浏览(112)

请原谅我,如果这是问其他地方(并提供一个链接!我没能找到一个完全相同的复制品。
我不确定我是否正确地使用了Q。
作为一个最小的例子:

#include <cstdint>
#include <vector>

class Priv {
protected:
    // All members of Priv are protected and should not be accessed directly.
    using Typ = uint16_t;
    //   (In reality, Typ is defined based on various macro definitions.)
    // ...
    // However, I would like to give access to classes I specifically befriend.
    // All instantiations of Public should be permitted, regardless of T.
    template <typename T> friend struct Public;
};

// Default arguments in class Public's template parameter list should be able to 
// access protected members of Priv because Public has been friend-zone'd, right?
template <typename T = Priv::Typ>
struct Public: std::vector<T> {
    inline Public(): std::vector<T>() {}
};

int main() {
        Public pub; // should default to Public<Priv::Typ>
}

字符串
但不幸的是,我似乎对朋友的声明是错误的:

<source>:17:30: error: 'using Typ = uint16_t' is protected within this context
   17 | template <typename T = Priv::Typ>
      |


有人能指出我的错误吗?

pzfprimi

pzfprimi1#

默认的模板参数在类作用域之外,而不是在类作用域之内。它使Public<>等价于Public<Priv::Typ>,其中参数显然是在用户的上下文中使用的,而不是类。所以在这个上下文中不应该使用protected成员。
您只能在friend的作用域内使用类的private/protected成员。因此,如果您希望类模板的用户能够隐式或显式地指定类型,同时仍然将Typ标记为protected,则需要在类范围内以某种方式转换为Typ。举例来说:

struct PrivTypProxy;

template <typename T = PrivTypProxy>
struct Public:
    std::vector<
        std::conditional_t<
            std::is_same_v<T, PrivTypProxy>,
            Priv::Typ,
            T
         >
      >
{
    using U = std::conditional_t<
                  std::is_same_v<T, PrivTypProxy>,
                  Priv::Typ,
                  T
               >;
    inline Public(): std::vector<U>() {}
};

字符串
但我不清楚这样做的意图是什么。

相关问题