推论忽略的参数包

Posted

技术标签:

【中文标题】推论忽略的参数包【英文标题】:Parameter pack ignored by deduction 【发布时间】:2017-03-12 14:48:09 【问题描述】:

如果参数包没有出现在函数的参数列表的末尾,为什么我的gcc-5.4.0 不能推断出参数包?虽然对works 的调用以正确的方式推导出到works<int,int,int>,但对fails 的调用并没有被推导出来,而是只假定一个空参数包。导致有关函数提供的参数过多的错误消息。

#include <iostream>

template <typename...args_t>
void works (int first, args_t...args) 
    std::cout << __PRETTY_FUNCTION__ << std::endl;


template <typename...args_t, typename last_t, typename=void>
void fails (args_t...args, last_t last) 
    std::cout << __PRETTY_FUNCTION__ << std::endl;


int main () 
    works (0, 1, 2, 3);
    fails (0, 1, 2, 3);
    return 0;

编辑: 正如答案所解释的,参数包后不允许有类型名。但是根据cppreference.com的说法,后面有其他模板参数应该是有效的,如果可以推导出来的话。显然给定的例子不能用我的gcc 编译。相反,对于太多给定参数,它仍然存在相同的错误。

#include <iostream>
template <typename...args_t, typename U, typename=void>
static int valid (args_t...args, U u) 
    std::cout << __PRETTY_FUNCTION__ << std::endl;
    return u;


int main () 
    return valid(0, 0.0, -1, 3u);

【问题讨论】:

你是在问如果这些是规则还是为什么这些是规则? 因为gcc 不编译它,我希望它是规则。由于我找不到任何关于为什么会这样,我很高兴听到它的原因。当然我也想看看绕过它的方法.. (; @Jonas 它与其他编译器以同样的方式失败。 Cppreference 已修复(函数参数的顺序错误) 【参考方案1】:

如果参数包没有出现在函数的参数列表的末尾,为什么我的gcc-5.4.0 不能推断出参数包?

因为你不能像这样指定可变参数包之外的任何类型

 void fails (args_...args, int last)
                      // ^^^^^^^^^^

这只是与默认参数值或普通省略号 (...) 相同的问题,它们需要在参数列表的末尾打开(或者说它们必须是最后一个元素):

 void fails(int x = 0, int last);
 void fails(int x, ..., int last);

【讨论】:

以上是关于推论忽略的参数包的主要内容,如果未能解决你的问题,请参考以下文章

TS-- 类型推论类型兼容性高级类型

LayaBox---TypeScript---类型推论

返回类型推论与解包引用的混淆

yum

如果有参数,SpringBoot websecurity 不会忽略 url

Python argparse 忽略无法识别的参数