【问题标题】:Template base class accessible when inheriting from a specific specialization?从特定专业继承时可访问的模板基类?
【发布时间】:2018-06-24 10:21:51
【问题描述】:

前几天,我发现这是可能的:

template <class T> struct base {};
struct derived: base<int> {};

int main()
{
    // The base class template is accessible here
    typename derived::base<double> x;

    // from the comments, even this works
    typename derived::derived::base<double>::base<int>::base<void> y;
}

我不记得曾经在 cppreference 或 C++ 教程中阅读过这篇文章,或者在巧妙的模板元编程技巧中使用过这篇文章(因为我确信它可以)。我有几个问题:

  • 这东西有具体的名字吗?
  • 它在 C++ 标准和 cppreference 中的什么地方记录?
  • 是否有任何模板元编程技巧可以利用这一点?

【问题讨论】:

  • 请注意,base&lt;double&gt; 不是derived&lt;int&gt; 的基类。
  • @MarkRansom 我不认为这是完成任何事情的尝试。相反,这是一个奇怪的观察。在您期望需要使用命名空间 space 限定 base&lt;double&gt; 的地方,在此示例中使用 derived&lt;int&gt; 似乎可以完成同样的事情。
  • 仅供参考,clang 给出以下警告,这让我认为这是不合法的 c++:&lt;source&gt;:7:57: warning: ISO C++ specifies that qualified reference to 'base' is a constructor name rather than a template name in this context, despite preceding 'typename' keyword [-Winjected-class-name] typename derived::derived::base&lt;double&gt;::base&lt;int&gt;::base&lt;void&gt; x;,箭头指向最后一个 base 的开头。
  • 更简单的版本似乎在这里抛弃了一些实用程序,因为base 不再位于远程命名空间中。

标签: c++ c++11 inheritance language-lawyer template-meta-programming


【解决方案1】:

正如@Nir Friedman 在comment 中指出的那样,typename derived::derived::base&lt;double&gt;::base&lt;int&gt;::base&lt;void&gt; y; 实际上可能是格式错误的,因为derived::derived::base&lt;double&gt;::base&lt;int&gt;::base 被视为base 的构造函数,根据[class.qual]/2


  • 这个东西有具体的名字吗?

它被称为 injected-class-name

  • 它在 C++ 标准和 cppreference 中的什么地方记录?

在标准中:[class]/2 指定类的名称被视为该类的公共成员。 [temp.local] 指定类模板的注入类名可以用作 template-nametype-name

关于 cppreference:它(不完全)记录在 http://en.cppreference.com/w/cpp/language/unqualified_lookup#Injected_class_name 中。

  • 是否有任何模板元编程技巧可以利用这一点?

我不知道有任何此类技巧,尽管在日常使用中,只要当前类在类定义中被命名,就会使用注入类名称:

template<class T>
struct A {
    A<T>& operator=(const A<T>&); // injected-class-name as template-name
    A& operator=(A&&); // injected-class-name as type-name
};

后者可能被故意用来缩短成员声明。

基类的注入类名主要(无意识地)在成员初始化列表中使用:

struct B : A<int> {
    B() : A() {}
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-01
    • 1970-01-01
    相关资源
    最近更新 更多