我根本无法编译。我可能不可能,但我不知道为什么不应该这样。
class A {
template <typename T>
class B {
int test() { return 0; }
};
//template <> class B<int>; <-with this, namepace error
B<int> myB_;
};
template <> class A::B<int> {
int test() {
return 1;
}
};
看起来编译器抱怨“显式特化”类A :: B“必须在使用之前声明。” 如果我尝试在注释行中提供froward声明,编译器会抱怨 “显式特化”B“必须在包含模板的命名空间中声明。” 我们在这里使用2个不同的编译器。此错误来自IBM在AIX上的“xl”编译器,但在我们的Sun系统上进行编译时,我会遇到类似的错误。 这似乎是一个抓住22。
显然,这是一个非常人为的,简单化的例子,但它代表了问题。 我想在类中定义一个模板类,因为模板类只与包含类相关。不应该从课堂外访问模板。
我错过了什么吗?
答案 0 :(得分:3)
你是对的。这是不可能的(据我所知)。在声明显式特化之前,您的成员声明会导致隐式实例化。但是你想怎么声明呢?你不能在课堂范围内这样做。其他人感到this is an ugly restriction。
你可以通过使类成员成为指针来解决这个问题。这不需要在该点隐式实例化类,而是在最后创建对象的位置。我意识到这是一个丑陋的工作。所以最好找到其他方法来做到这一点。
例如,在类范围中允许部分特化。因此,您可以添加一个虚拟模板参数,然后您可以在成员声明之前在类中对此进行专门化。同样,我觉得这很难看,但我觉得它不会打扰那么多东西。
答案 1 :(得分:0)
您可以通过使用未命名的隐私命名空间来解决此问题:
namespace {
template <typename T>
class B {
int test() { return 0; }
};
template <> class B<int> {
int test() {
return 1;
}
};
}
class A {
B<int> myB_;
};
这将编译,但如果A
需要在此编译单元外可见,则需要更复杂的机器(例如,接口和工厂或Pimpl)
答案 2 :(得分:0)