双模板方法的部分特化失败
有模板类List。
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
编译器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
There is the template class List.
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)
}
How to specialize method load for N=2? This code is not valid...
template <typename Point>
void List <Point> <2>::load ( const char *file)
{
}
And this code also does not work.
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
Compiler 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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
事实证明,C++ 规范中有一项规定明确禁止专门化模板类或嵌套在模板类内的函数,除非您也明确专门化外部模板。 Visual Studio 不强制执行此规则,因此与前面的示例混淆,但 g++ 确实执行此规则。
如果您想专门化模板,您的选择要么是也专门化外部模板,要么以某种方式通过根据模板参数将方法分派到两个不同实现之一来伪造专门化的行为。我知道,这些都不是很令人满意,但不幸的是,该语言在某些模板角落设计得很奇怪。 :-(
模拟显式专业化行为的一种方法是使用一种称为标记分派的技术。这个想法是我们将创建一个非常简单的结构,如下所示
:完全是空的。它并不意味着可以直接使用,而只是将整数嵌入到类型系统中的一种方式。特别是,
Box<3>
与的类型不同。 Box<4>
等。接下来,在列表类中,定义两个如下所示的函数,最好标记为私有:
这两个函数是彼此的重载,只能通过它们的最终参数来区分,该参数可以是模板情况下的
Box
或非模板情况下的Box<2>
请注意,参数没有名称。 ,但由于我们不打算实际读取参数,因此我们不需要它们。这些函数背后的直觉是,第一个函数将是适用于任何N< 的“包罗万象”的实现。 /code> 除 2 之外。第二个版本将包含
N == 2
情况下的加载实现。最后,按如下方式实现
load
:这是如何工作的?该函数接受一个参数,然后调用
doLoad
将该参数作为第一个参数转发,并传递一个临时Box
作为第二个参数。如果N
不是 2,则这是对doLoad
模板版本的调用,它是包罗万象的处理程序。另一方面,如果N
为 2,则这将调用doLoad
的非模板版本,因为在重载解析期间非模板函数比模板函数具有优先级。简而言之,
load
的实现只是变成了一个蹦床,将您转发到两个实现中正确的一个。然后,您可以将逻辑放入适当的doLoad
函数中以获得您想要的行为。希望这有帮助!
It turns out that there's a provision in the C++ spec that explicitly disallows specializing a template class or function nested inside of a template class unless you also explicitly specialize the outer template as well. Visual Studio doesn't enforce this rule, hence the confusion with the previous example, but g++ certainly does.
If you want to specialize the template, your options will either be to also specialize the outer template or to somehow fake up the behavior of specialization by having the method dispatch to one of two different implementations based on the template parameter. Neither of these are very satisfying, I know, but unfortunately the language is designed weirdly in some template corners. :-(
One way that you can emulate the behavior of the explicit specialization is to use a technique called tag dispatching. The idea is that we'll make a very simple struct that looks like this:
This type is completely empty. It's not meant to be used directly, but rather is just a way of embedding an integer into the type system. In particular,
Box<3>
is not the same type asBox<4>
, etc.Next, in your list class, define two functions that look like this, preferably marked private:
These two functions are overloads of one another, distinguishable only by their final parameter, which is either a
Box<N>
in the template case or aBox<2>
in the non-template case. Note that the parameters don't have names. This is an arbitrary decision, but since we're not planning on actually reading the parameters, we don't need them. The intuition behind these functions is that this first function will be the "catch-all" implementation that will work for anyN
except 2. The second version will contain the implementation of loading for the case whereN == 2
.Finally, implement
load
as follows:How does this work? This function takes in a parameter, and then calls
doLoad
forwarding that parameter as the first argument and passing a temporaryBox<N>
as the second argument. IfN
is not two, then this is a call to the template version ofdoLoad
, which is the catch-all handler. If, on the other hand,N
is two, then this will call the non-template version ofdoLoad
, because non-template functions have priority over template functions during overload resolution.In short, the implementation of
load
just becomes a trampoline to forward you to the correct of the two implementations. You can then put the logic in the appropriatedoLoad
function to get the behavior you want.Hope this helps!
编辑:
好的,所以我用内联函数定义稍微重写了你的类,这绝对有效:
Edit:
Ok, so I rewrote your class a bit, with inlined function definitions, and this definitely works:
如果不专门化类模板,则无法专门化成员模板。
我还想知道 N 的含义是什么,因为它没有在函数参数中使用?
You cannot specialize a member template without also specializing the class template.
I also wonder what the meaning of N could be, as it is not used in the function parameter?