无参数可变参数模板上的模棱两可的重载 [英] Ambiguous overload on argument-less variadic templates
问题描述
相关:
- Ambiguous overload accessing argument-less template functions with variadic parameters
- Simple variadic template function can't instantinate
- Why is this variadic function ambiguous?
考虑这对可变参数模板:
Consider this pair of variadic templates:
template<typename Dummy>
bool All(Param& c) {
return true;
}
template<typename Dummy, Func* f, Func* ...rest>
bool All(Param& c) {
return f(c) && All<Dummy, rest...>(c);
}
这有效并且可以编译。但是,如何在没有第一个模板参数的情况下编写它?
This works and compiles. However, how to write it without the first template parameter?
听起来微不足道?好吧,这就是我的想法。 :-)让我们考虑一些想法。
Sounds trivial? Well, that's what I thought. :-) Let's consider some ideas.
template<Func* f, Func* ...rest>
bool All(Param& c) {
return f(c) && All<rest...>(c);
}
template<>
bool All(Param& c) {
return true;
}
不起作用...当我尝试此操作时,我想到了专业化
Won't work... When I attempted this I had specialization in mind, but on the second thought that's not how it works.
在原始示例中,我创建了两个不同的重载模板,第一个采用1个模板参数,第二个采用2个或更多参数。没有歧义,没有专业化。 我说得对吗?
In the original example I created two different templates of overloads, first taking 1 template parameter and second taking 2 or more. No ambiguities and no specialization involved. am I getting it right?
bool All(Param& c) {
return true;
}
template<Func* f, Func* ...rest>
bool All(Param& c) {
return f(c) && All<rest...>(c);
}
显然不起作用,全部<休息。 ..>
且 rest ...
为空不会扩展为对非模板函数的调用。
Won't work obviously, All<rest...>
with rest...
being empty won't expand to a call to a non-template function.
让我们重新构建解决方案。
Let's rebuild the solution a bit.
template<Func* f>
bool All(Param& c) {
return f(c);
}
template<Func* f, Func* ...rest>
bool All(Param& c) {
return f(c) && All<rest...>(c);
}
这是不可行的,因为All(c)会含糊。因此,我需要一个0-arg情况和一个> 0-arg情况...或者1-arg情况和一个> 1-arg情况呢?
This one is a no-go, because All(c) would be ambiguous. Hence I need to have a 0-arg case and a >0-arg case... Or what about a 1-arg case and a >1-arg case?
想法#3.5:
template<Func* f>
bool All(Param& c) {
return f(c);
}
template<Func* f, Func* f2, Func* ...rest>
bool All(Param& c) {
return f(c) && All<f2, rest...>(c);
}
是的,可以,但是包含copypasta(在这种情况下很简单,但是可能更大!),因此我想说这并不比我刚开始做的更好。
Yup, works, but contains copypasta (simple in this case but might be bigger!), hence I'd say it's no better than what I've started with. Just another workaround.
让我们尝试#1,但使用类而不是函数。
Let's try #1 but with classes instead of functions.
template<Func* f, Func* ...rest>
struct All {
static bool func(Param& c) {
return f(c) && All<rest...>(c);
}
};
template<>
struct All {
static bool func(Param& c) {
return true;
}
};
这看起来很有希望,因为我可以专门上课。但是,嘿,这是什么?
This looks promising since I can specialize classes. But hey, what is it?
对不起,未实现:无法将'rest ...'扩展为定长参数列表
sorry, unimplemented: cannot expand 'rest ...' into a fixed-length argument list
这不是GCC 4.4吗?我在MinGW GCC 4.6.1(tdm-1)上。
Wasn't this a GCC 4.4 thing? I'm on MinGW GCC 4.6.1 (tdm-1).
无论如何,我认为我不能做这样简单的方法吗?是否需要使用具有附加虚拟模板参数的替代方法来完成此任务?
Anyway, should I think that I cannot do such an elementary thing in a straightforward way? Is it required to use the workaround with an additional dummy template parameter to accomplish this task?
还是存在简单,正确的变体来指定零参数情况,哪个可行?
Or is there a simple, correct variant to specify the zero-argument case, which would work?
推荐答案
在这种情况下,由于模板参数是非类型的,因此
如果我们准备一个带有默认模板参数的函数,例如
,则可以保存 Dummy
参数:
In this question's case, since template parameters are non-type,
if we prepare a function with default template argument like the
following, Dummy
parameter can be saved:
template<typename = void>
bool All(Param& c) {
return true;
}
template<Func* f, Func* ...rest>
bool All(Param& c) {
return f(c) && All<rest...>(c);
}
但是,我不确定这是否总是适用。
对于更一般的情况,可能需要
std :: enable_if
或类似的调度方法(尽管这样会使代码有些冗长)。
However, I'm not sure this is always applicable.
For more general case, std::enable_if
or similar dispatch might be needed
(this will make the code a little lengthy though).
这篇关于无参数可变参数模板上的模棱两可的重载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!