可选的参数后,模板参数包的据称已知长度的参数包
我试图用一种可选的参数具有一种“调用”功能:
template <typename... T>
void foo(void func(T...), T... args, int opt = 0)
{
func(args...);
}
void bar(int, int);
int main()
{
foo(&bar, 1, 2, 3);
}
我本来可以期望这是有效的,因为参数pak可以从第一个参数中推导出来,但是显然编译器具有不同的想法:
<source>:11:5: error: no matching function for call to 'foo'
foo(&bar, 1, 2, 3);
^~~
<source>:2:6: note: candidate template ignored: deduced packs of different lengths for parameter 'T' (<int, int> vs. <>)
void foo(void func(T...), T... args, int opt = 0)
^
1 errors generated.
Compiler returned: 1
为什么要推论长度0的列表?我可以强迫它忽略args
以扣除的目的吗?或更一般而言,我该如何完成这项工作?
I am trying to have a kind of "invoke" function with an optional argument at the end:
template <typename... T>
void foo(void func(T...), T... args, int opt = 0)
{
func(args...);
}
void bar(int, int);
int main()
{
foo(&bar, 1, 2, 3);
}
I would have expected this to work, since the parameter pack can be deduced from the first argument, but clearly the compilers have different ideas:
<source>:11:5: error: no matching function for call to 'foo'
foo(&bar, 1, 2, 3);
^~~
<source>:2:6: note: candidate template ignored: deduced packs of different lengths for parameter 'T' (<int, int> vs. <>)
void foo(void func(T...), T... args, int opt = 0)
^
1 errors generated.
Compiler returned: 1
Why is it deducing a list of length 0? Can I force it to ignore args
for the purposes of deduction? Or more generally, how can I make this work?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以使其重载,而不是可选的参数。但是,您需要将“可选”移至参数包之前。
然后,第二个过载将使用“默认”参数集将参数转发到第一个。
您可能需要将可选的一路移动到第一个位置,以使功能及其参数在一起。这是一个味道。
另一个选项可能是排除可选参数,并且仅具有参数pack,并在存在时提取可选参数,或者如果没有,则使用默认值。
这要求您限制
func
的签名以匹配您要调用的功能。以第二版为基础,但给予更多自由,您可以为
func
引入单独的参数包。如果该包的大小与所提供的参数相同,则需要为opt
选择一个默认值。另一方面,如果它包含的比该功能所需的更多参数,则可以选择用于opt
的额外参数之一。在下面的示例中,我刚选择了第一个额外参数。You could make it overloaded instead of having an optional argument. You'd need to move the "optional" to before the parameter pack though.
The second overload would then just forward the arguments to the first, with the "default" parameter set.
You might want to move the optional all the way to the first position to let the function and its parameters be together. It's a matter of taste.
Another option could be to exclude the optional parameter and only have the parameter pack and to extract the optional if it's present or use the default value if it's not.
This requires that you restrict the signature of
func
to match the function you aim to call.Building on the second version but giving a lot more freedom, you could introduce a separate parameter pack for
func
. If that pack has the same size as pack of arguments supplied, you need to pick a default value foropt
. If it on the other hand contains more arguments than needed for the function, you can select which one of the extra arguments that should be used foropt
. In the example below, I just picked the first extra parameter.您可以将函数参数放在a
std :: tuple
< < /a>,使它们与您的可选参数不同。C ++ 17提供
std :: apply
为您打开元组参数。You can put the function arguments in a
std::tuple
, to make them distinct from your optional parameter.C++17 provides
std::apply
to unpack the tuple parameters for you.