【发布时间】: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<int>。您似乎期望编译器为每个可能的类型T实例化A<X<T>>,希望可能存在恰好有成员typedef int Titem的特化(或证明不存在这样的成员)。或者进行定理证明练习以证明,在A的当前可见定义和特化下,不可能有T可能导致A< X<T> >::Titem成为int。编译器不会那么费劲;它反而将T声明为不可演绎的上下文,并且从不使用这种特化。
标签: c++ c++11 templates specialization typename