使用可变参数模板的 mixin 继承的可见性规则
Visibility rules for mixin inheritance with variadic template
假设我从可变参数模板继承了整个参数列表。参数是如何继承的?
// snippet
template<typename... R>
class foo
: public R... {
public:
};
// ....
using foo_inst = foo<bar_1, bar_2>;
我试过了,好像所有 R
的都是继承的public(不只是第一个)。 这是定义的行为吗?
我用 gcc 和 msvc 试过了(感谢 also with clang), all with same results. The compilers not even mentioned any warnings. You can see a running example here。
是的,这是定义的行为。引用自 14.5.3[temp.variadic]
A
pack expansion
consists of a
pattern
and an ellipsis, the instantiation of which produces zero or more
instantiations of the pattern in a list (described below). The form of the pattern depends on the context in
which the expansion occurs. Pack expansions can occur in the following contexts:
该列表中的相关上下文是:
— In a base-specifier-list (Clause 10 ); the pattern is a
base-specifier.
因此,在参数包扩展class foo : public R...
中,模式是base-specifierpublic R
,使得包由类型[=13]组成=] 扩展为 public T1, public T2, ... , public Tn
。 (上一句中的省略号用于数学序列指定意义。)
假设我从可变参数模板继承了整个参数列表。参数是如何继承的?
// snippet
template<typename... R>
class foo
: public R... {
public:
};
// ....
using foo_inst = foo<bar_1, bar_2>;
我试过了,好像所有 R
的都是继承的public(不只是第一个)。 这是定义的行为吗?
我用 gcc 和 msvc 试过了(感谢
是的,这是定义的行为。引用自 14.5.3[temp.variadic]
A pack expansion consists of a pattern and an ellipsis, the instantiation of which produces zero or more instantiations of the pattern in a list (described below). The form of the pattern depends on the context in which the expansion occurs. Pack expansions can occur in the following contexts:
该列表中的相关上下文是:
— In a base-specifier-list (Clause 10 ); the pattern is a base-specifier.
因此,在参数包扩展class foo : public R...
中,模式是base-specifierpublic R
,使得包由类型[=13]组成=] 扩展为 public T1, public T2, ... , public Tn
。 (上一句中的省略号用于数学序列指定意义。)