【发布时间】:2021-04-29 12:00:55
【问题描述】:
考虑这段代码:
template <typename T>
class Singleton
{
};
class Logger : public Singleton<Logger> {
friend class Singleton;
};
它在 gcc 和 clang 中编译,但它有效吗? [temp.local].1 说:
当它与模板参数列表一起使用时,作为模板模板参数的模板参数,或作为朋友类模板声明的详细类型说明符中的最终标识符,它是一个引用类模板本身的模板名称。
粗体部分似乎适用,朋友声明似乎需要类型名称而不是模板名称(参见 [class.friend])。
是编译器错误还是我误读了标准?
【问题讨论】:
-
我认为需要
friend class Singleton<Logger>;才能允许模板基类的特定实例化成为朋友,而不是模板的所有可能实例化。跨度> -
@RemyLebeau - 结交 all 实例化将是
template <class L> friend class Singleton<L>;- 不是 OP 中的内容。 -
[temp.local](作为 [temp.res] 的子部分)主要是关于在 模板定义。事实上,如果有人修改您的示例GCC 会立即拒绝该代码。我不确定该部分是否同样适用于非模板中使用的注入类名称。
-
@StoryTeller-UnslanderMonica your example 落在 [temp.dep]/3。即使a more simple one 也是如此。
-
粗体部分不适用,因为名称不在“朋友类模板声明”(如
template <class> friend class Singleton;)中,只是“朋友类声明”。
标签: c++ language-lawyer class-template friend-class injected-class-name