【问题标题】:Template structure specialization using typename ::使用 typename :: 的模板结构特化
【发布时间】:2017-02-14 14:41:14
【问题描述】:

我想用在另一个结构 A 中定义的类型来专门化结构 B。

人们可以在帖子中看到 MWE。

首先我很惊讶 B 的两个专业可以同时存在。我添加了第二个来显示问题。如果删除,代码看不到 B 的适当特化。 我宁愿只保留第一个专业。

所以,我的问题是:

  • 为什么 B 的两个特化可以同时存在?
  • 为什么第一个不适用于 main 的实例化?

定义.h:

template <class T>
class X {};

template <class T>
class Xitem {};


template <class T>
struct A;

template <class T>
struct A< X<T> > {
    typedef Xitem<T> Titem;
};

template <class T>
struct B;

template <class T>//I need this one only
struct B< typename A< X<T> >::Titem > {
    static void foo() {
        std::cout << "foo 1" << std::endl;
    }
};

template <class T>
struct B< Xitem<T> > {
    static void foo() {
        std::cout << "foo 2" << std::endl;
    }
};

main.cpp:

#include "definitions.h"

int main(int argc, char *argv[]) {

    B< A< X<int> >::Titem >::foo();
}

输出:“foo 2” 使用 Xcode 7

【问题讨论】:

  • 我猜这违反了单一定义规则,编译器只是“挑选”了一个来执行,但我并不完全确定该评估。
  • 第一个永远不能用,因为T不能推导出来。最近,that causes the program to be ill-formed.
  • 我认为它不需要第一次专业化,因为它无法解析 T 的类型。gcc 给了我一个错误消息,编译你的代码:模板参数在部分专业化中不可推导。如果我明确命名模板中使用的类型(int 而不是 T),它可以工作,但显然不是你想要的。
  • 感谢您的 cmets。所以,长话短说,用“typename ::”(不知道怎么称呼它)专门化一个结构是不可能的?前提是涉及模板
  • 想象一下,你使用的是B&lt;int&gt;。您似乎期望编译器为每个可能的类型 T 实例化 A&lt;X&lt;T&gt;&gt;,希望可能存在恰好有成员 typedef int Titem 的特化(或证明不存在这样的成员)。或者进行定理证明练习以证明,在A 的当前可见定义和特化下,不可能有T 可能导致A&lt; X&lt;T&gt; &gt;::Titem 成为int。编译器不会那么费劲;它反而将 T 声明为不可演绎的上下文,并且从不使用这种特化。

标签: c++ c++11 templates specialization typename


【解决方案1】:

Igor Tandetnik 在 cmets 中给出的答案:

假设您使用 B。您似乎期望编译器为每个可能的类型 T 实例化 A>,希望可能存在恰好具有成员 typedef int Titem 的特化(或证明没有这样的)。或者进行定理证明练习,以证明在当前可见的定义和 A 特化的情况下,不可能的 T 可能导致 A::Titem 是一个 int。编译器不会那么费劲;相反,它声明 T 是不可演绎的上下文,并且从不使用这种特化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-22
    • 2012-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多