2016-11-15 44 views
4

模板特考虑下面的代码:的内部类

struct X 
{ 
    template <typename T> 
    class Y 
    {}; 
}; 
template<> 
class X::Y<double>{ 
}; 

在这里,我们是专业的类型的Y舱双和代码工作正常。问题是,如果我的代码改成这样:

template<typename A> 
struct X 
{ 
    template <typename T> 
    class Y 
    {}; 
}; 
template<typename A> 
class X<A>::Y<double>{ 
}; 

编译器会报告错误:

'X::Y': explicit specialization is using partial specialization syntax, use template <> instead!

剂量任何一个知道我可以专注Y类在这种情况下?

+0

请问做什么错误消息说没有帮助?使用'template <>'而不是'template '嵌套模板专门化。 –

+0

它不工作!我也厌倦了这一点: template <> class X :: Y { }; – MEMS

回答

2

简单的答案 - 你不能完全专门化模板化的内部类的模板外部类。但如果你真的想达到类似的效果,你可以尝试用虚拟的缺省模板参数偏特:

#include <iostream> 

template<typename A> 
struct X 
{ 
    template <typename T, T* =nullptr> 
    class Y{}; 
}; 

template<typename A> 
template<double *Ptr> 
class X<A>::Y<double, Ptr> { 
public: 
    static constexpr int value = 1; 
}; 

int main() { 
    std::cout << X<int>::Y<double>::value << std::endl; 
} 

[live demo]

+1

书:经典的C++高级元编程,第33页说: 模板专业化是有效的仅在命名空间级别: 结构X { 模板 Y类 {}; template <> //非法,但通常被编译器容忍 class Y {}; }; template <> // legal class X :: Y { }; 所以你做了什么可能会工作,但并不总是! – MEMS

+0

@MEMS您的作者可能是对的。在查找标准示例后,我意识到我可能实际上是在解释'[temp.class.spec]/5'。根据C++标准核心语言活动问题'更新代码 –

+1

@MEMS'727。成员类的内联显式专业化内联部分专业化很好地形成......所以我以前的代码确实是有效的。请查找[参考](http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#727) –

3

你不能专门化内部模板类而不明确地专门化外部模板类。 See this question for more details and a quote from the standard.

解决方法:创建一个外部类,在一个具体的命名空间既需要TA和别名它里面X

namespace impl 
{ 
    template <typename A, typename T> 
    struct Y { }; 
} 

template<typename A> 
struct X 
{ 
    template <typename T> 
    using Y = impl::Y<A, T>; 
}; 

如果你是罚款明确专攻内部和外部类,可以使用以下语法:

template <> 
template <> 
class X<int>::Y<double> 
{ 
    // ... 
}; 

Example on wandbox

+0

如果我想将它专门化为特定的X和Y,请执行以下操作: template <> class X :: Y { }; 在这种情况下它也抱怨!它说:错误C2992:'X :: Y ':无效或缺少模板参数列表 – MEMS

+0

@MEMS:您需要双'template <>'。 [wandbox示例](http://melpon.org/wandbox/permlink/5QsXzayEWYB8Vz1E)。 –

+0

也更新了我的答案。 –