提问人:ardnew 提问时间:7/31/2023 最后编辑:ardnew 更新时间:7/31/2023 访问量:59
如何将外部类的受保护成员引用为类模板的构造函数的默认参数
How to refer to protected members of an external class as default arguments for a constructor of a class template
问:
如果在其他地方被问到这个问题,请原谅我(并提供链接!我找不到一个完全重复的。
不确定我是否正确地表达了 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>
|
有人可以指出我的错误吗?
答:
1赞
user17732522
7/31/2023
#1
默认模板参数在类作用域之外,而不是在类作用域内。它等价于在用户上下文中使用参数的位置,而不是类。因此,在此上下文中不应使用成员。Public<>
Public<Priv::Typ>
protected
您只能在 的作用域内使用类的 / 成员。因此,如果您希望类模板的用户能够隐式或显式指定类型,同时仍然标记 ,那么您需要以某种方式在类范围内进行转换。例如:private
protected
friend
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>() {}
};
但我不清楚这样做的目的是什么。
评论
0赞
ardnew
7/31/2023
你说因为受到保护。但是,如果不授予对单个类的访问权,那么这些类又有什么意义呢(由于、等)呢?So it shouldn't be possible to use a protected member in this context.
Typ
Friend
protected
pritvate
1赞
Ted Lyngmo
7/31/2023
@ardnew 关键是,它不是尝试访问 的实例,而是外部用户尝试使用 .Public<Priv::Typ>
Public
Priv::Typ
Public
Priv::Typ
0赞
user17732522
7/31/2023
@ardnew 默认模板参数不属于任何类。它仅用于形成模板用户对的类模板专用化(然后它本身就是一个好友的类)。
1赞
user17732522
7/31/2023
@ardnew 知道或不知道什么类型的别名与是否应该允许用户使用别名完全正交的问题。您似乎希望不允许用户显式命名别名,但仍然通过模板参数推导隐式命名它。我不清楚为什么需要限制显式使用。Priv::Typ
1赞
Ted Lyngmo
7/31/2023
@ardnew我认为在不改变设计的情况下,你无能为力。你问你的错误是什么,并得到了答案。我只会接受答案并重新考虑设计。
评论
Priv
Typ
public
Typ
public
Public<>
Public<Priv::Typ>
protected