C++ 双模板方法的部分专门化失败

C++ 双模板方法的部分专门化失败,c++,templates,specialization,partial-specialization,C++,Templates,Specialization,Partial Specialization,这是模板类列表 template <typename Point> class List { public: template <const unsigned short N> void load ( const char *file); ... }; template <typename Point> template <const unsigned short N> vo

这是模板类列表

template <typename Point>
class List
{


    public:
          template <const unsigned short N>
          void load ( const char *file);
          ...
};

template <typename Point>
template <const unsigned short N>
void List <Point>::load ( const char *file)
}
模板
班级名单
{
公众:
模板
无效加载(常量字符*文件);
...
};
模板
模板
无效列表::加载(常量字符*文件)
}
如何专门化N=2的方法加载?此代码无效

template <typename Point>
void List <Point> <2>::load ( const char *file)
{
}
模板
无效列表::加载(常量字符*文件)
{
}
而且这个代码也不起作用

template <typename Point>
void List <Point> ::load <2> ( const char *file )
{ 
}

Error 3 error C2768: 'List<Point>::load' : illegal use of explicit template arguments 66. 
Error 5 error C2244: 'List<Point>::load' : unable to match function definition to an existing declaration 66
模板
无效列表::加载(常量字符*文件)
{ 
}
错误3错误C2768:“列表::加载”:非法使用显式模板参数66。
错误5错误C2244:“列表::加载”:无法将函数定义与现有声明匹配66
编译器g++:

template <typename Point>
template <>
void List <Point> ::load <2> ( const char *file )
{
}

error: explicit specialization in non-namespace scope `class List<>'
error: enclosing class templates are not explicitly specialized
error: default arguments are only permitted for function parameters
error: `load' is not a function template
error: invalid function declaration
模板
模板
无效列表::加载(常量字符*文件)
{
}
错误:非命名空间范围“类列表”中的显式专门化
错误:封闭类模板未显式专用
错误:默认参数仅允许用于函数参数
错误:`load'不是函数模板
错误:无效的函数声明
编辑: 好的,我用内联函数定义重写了你的类,这确实有效:

template <typename Point>
class List
{
public:
    template <const unsigned short N>
    void load( const char *file){
    }

    template<>
    void load<2>(const char* file){
    }
};
模板
班级名单
{
公众:
模板
无效加载(常量字符*文件){
}
模板
无效加载(常量字符*文件){
}
};

>P>证明了C++规范中有一个规定,它明确禁止在模板类内嵌套模板类或函数,除非您还显式地专门化外部模板。VisualStudio没有强制执行此规则,因此与前面的示例存在混淆,但g++肯定会执行此规则

如果您想专门化模板,您可以选择也专门化外部模板,或者通过基于模板参数将方法分派到两个不同实现之一,以某种方式伪造专门化行为。我知道,这两种语言都不是很令人满意,但不幸的是,该语言在某些模板方面设计得很奇怪-(

模拟显式专门化行为的一种方法是使用一种称为标记分派的技术

template <unsigned short N> struct Box {};
这是如何工作的?此函数接受一个参数,然后调用
doLoad
转发该参数作为第一个参数,并传递一个临时的
框作为第二个参数。如果
N
不是两个,则这是对模板版本的
doLoad
的调用,该模板版本是catch-all处理程序。如果,在e另一方面,
N
是2,那么这将调用非模板版本的
doLoad
,因为在重载解析期间,非模板函数比模板函数具有优先级

简而言之,
load
的实现只会成为一个蹦床,将您推向两个实现的正确方向。然后,您可以将逻辑放入相应的
doLoad
函数中,以获得您想要的行为


希望这有帮助!

如果不专门化类模板,就不能专门化成员模板


我还想知道N的含义是什么,因为它没有在函数参数中使用?

很抱歉,代码中有错误…所以我更新了我的问题。@Shelwien…谢谢你的链接。但我不完全清楚如何使用它…你能给我一个简短的例子吗?但它不起作用:错误3错误C2768:“列表::加载”:非法u显式模板参数se 66.错误5错误C2244:“列表::加载”:无法将函数定义与现有声明匹配66Ah,一个错误出现在
load
的函数定义中。它应该是
template List::load(char const*file){…}
。请让我快速检查其余部分…模板void List::load(常量字符*文件){}不起作用…@Robo:完全按照我在回答中的方式来做,而不是在类之外。@Xeo:不幸的是,标准中不允许IIRC在类定义中显式专门化,尽管MSVC可能允许它作为它的扩展。你能给我一个简短的例子吗?@Robo-当然!我会离开我的计算机一段时间,但是我会在我回来的时候做点什么。很棒的解决方法…它花了我很多时间……你是C++的主…谢谢你的时间和耐心。我需要决定在运行时不是在编译时使用哪个函数。但是模板是在编译时实例化的,不是运行时。对于运行时多态性,你使用虚拟函数。但是为值工作-也许一个switch语句就可以了?
template <unsigned short N>
    void doLoad(const char* file, Box<N>);
void doLoad(const char* file, Box<2>);
template <typename Point>
    template <unsigned short N>
void List<Point>::load(const char* file) {
    doLoad(file, Box<N>());
}