C++ 内部类的模板专门化

C++ 内部类的模板专门化,c++,metaprogramming,template-specialization,C++,Metaprogramming,Template Specialization,考虑以下代码: struct X { template <typename T> class Y {}; }; template<> class X::Y<double>{ }; struct X { 模板 Y类 {}; }; 模板 类X::Y{ }; 在这里,我们为double类型专门化了Y类,代码运行良好。问题是,如果我将代码更改为: template<typename A> struct X { temp

考虑以下代码:

struct X
{
    template <typename T>
    class Y
    {};
 };
template<>
class X::Y<double>{
};
struct X
{
模板
Y类
{};
};
模板
类X::Y{
};
在这里,我们为double类型专门化了Y类,代码运行良好。问题是,如果我将代码更改为:

template<typename A>
struct X
{
    template <typename T>
    class Y
    {};
 };
template<typename A>
class X<A>::Y<double>{
};
模板
结构X
{
模板
Y类
{};
};
模板
类X::Y{
};
编译器将报告一个错误:

“X::Y”:显式专门化正在使用部分 专门化语法,改用模板


有人知道在这种情况下我怎样才能专门化Y班吗

如果不显式地专门化外部模板类,就不能专门化内部模板类

解决方法:创建一个外部类,该类在详细名称空间中同时接受
T
A
,并在
X
内别名:

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

template<typename A>
struct X
{
    template <typename T>
    using Y = impl::Y<A, T>;
};
namespace impl
{
模板
结构Y{};
}
模板
结构X
{
模板

使用Y=impl::Y

这是一个简单的答案-您不能完全专门化模板化的外部类的模板化内部类。但是如果您确实想要实现类似的效果,您可以尝试使用伪默认模板参数进行部分专门化:

#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;
}
#包括
模板
结构X
{
模板
类Y{};
};
模板
模板

类X

执行错误消息所说的没有帮助的操作?在嵌套模板专门化上使用
template
而不是
template
。它不起作用!我也厌倦了这样做:模板类X::Y{};如果我想为特定的X和Y专门化它,比如:模板类X::Y{};在本例中,它也会抱怨!它说:错误C2992:'X::Y':模板参数无效或丢失list@MEMS……更新了我的答案。书:高级C++中的高级元编程,第33页说:模板特化仅在命名空间级别有效:StRtxx模板类y{};template//非法,但编译器类Y{};};template//合法类X::Y{};因此您所做的可能会起作用,但并不总是如此!@MEMS您的作者可能是对的。在查找标准示例后,我意识到我实际上可能过度解释了
[temp.class.spec]/5
。正在更新code@MEMS根据C++标准核心语言,主动问题<代码> 727。在类显式专业化成员类的内联部分化专业化良好。…所以我以前的代码确实是有效的。请找到
#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;
}