c++ - 双模板方法的部分专用化失败

  显示原文与译文双语对照的内容
0 0

有模板类列表。


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进行方法加载? 这里代码是 NOT 有效。


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

这段代码也能完成 NOT 工作。


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

编译器 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

时间: 原作者:

0 0

事实证明 C++ 规范中有一个规定,它显式禁止专门的模板类或者函数嵌套在模板类中,除非你也显式地专门化外部模板。 Visual Studio 不实施这个规则,因此与前面的示例混淆,但是 G++ 确实如此。

如果你想要专门化模板,你的选项也将是专门化外部模板的,或者通过将方法分派到基于模板参数的两种不同实现中的某种方式来伪造专门化行为。 我知道,这两种语言都不令人满意,但不幸的是,这些语言在一些模板。 :- (

可以模拟显式专用化行为的一种方法是使用称为标记调度的技术。 我们的想法是,我们将制作一个非常简单的结构,如下所示:


template <unsigned short N> struct Box {};

这里类型完全为空。 它是直接使用的NOT,但它只是一种将整数嵌入到类型系统中的方法。 特别是 Box<3>的NOT 与 Box<4>的类型相同。

接下来,在你的列表类中,定义两个类似这样的函数,最好标记为 private:


template <unsigned short N>
 void doLoad(const char* file, Box<N>);
void doLoad(const char* file, Box<2>);

这两个函数是彼此重载的,只有它们的最终参数可以区分,这是模板中的Box<N>,或者非模板案例中的Box<2> 。 请注意,参数没有名称。 这是一个任意的决定,但是由于我们是 NOT 计划的实际读取参数,我们不需要它们。 这些函数背后的直觉是,第一个函数将是"全部捕获"实现,它将在除 2以外的任何 N 。 第二个版本将包含用于 N == 2的加载的实现。

最后,按如下方式实现 load:


template <typename Point>
 template <unsigned short N>
void List<Point>::load(const char* file) {
 doLoad(file, Box<N>());
}

这是如何工作的这个函数接受一个参数,然后调用 doLoad 作为第一个参数,并将一个临时 Box<N> 作为第二个参数传递。 如果 N 是 NOT 2,那么这是对 doLoad的模板版本的调用,这是捕获的所有处理程序。 另一方面,如果 N 是2,那么这将调用 doLoad的非模板版本,因为非模板函数在重载解析期间优先于模板函数。

简而言之,load的实现只是变成了一个蹦床,把你转到了正确的两个实现。 然后可以将逻辑放入适当的doLoad 函数中,以获得所需的行为。

希望有帮助!

原作者:
0 0

编辑: 好,所以我重写了你的类,并内联函数定义,这绝对是有效的:


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

 template<>
 void load<2>(const char* file){
 }
};

原作者:
0 0

你不能专门专用化成员模板而不专门化类模板。

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

原作者:
...