不对可变参数模板实例调用函数

Doesn't instance call function to variadic template

我有写函数来推断我转发给函数的参数量。像这样:

template<typename Arg>
constexpr size_t get_init_size(Arg arg, size_t i) {
    return i + 1;
}

template<typename T, typename ... Args>
constexpr size_t get_init_size(T First_arg, Args ... args, size_t i) {
    return get_init_size(args... , i + 1);
}

auto create_ipv4_header() {
    size_t x = get_init_size(0b01, 0b10, 0b01, static_cast<size_t>(0));
    return x //<= must return 3
}

但是编译器写: 错误:没有匹配函数来调用 'get_init_size(int, int, int, size_t)' 所以可变参数模板有问题吗?如果我将可变参数模板更改为如下内容,还有一件事:

template<typename T, typename ... Args>
constexpr size_t get_init_size(T First_arg, Args ... args, size_t i = 0)

我可以放下最后一个参数吗?(我没有用可变参数模板测试它)谢谢你的帮助!

你不需要写一个递归的模板函数来做这个,你可以在参数包的类型上使用sizeof...()运算符直接得到元素的数量:

template<typename... Args>
constexpr std::size_t get_init_size(Args&&...) {
    return sizeof...(Args);
}

查看实际效果 here

你的函数不行是因为贪心推导了一个参数包;意思是 Args... args 匹配 0b100b01 static_cast<size_t>(0)。然后因为不再有匹配 size_t i 的参数,替换失败,剩下的唯一候选者是 get_init_size() 的第一个版本,当然也不是匹配项。在参数包之后总是很难或不可能有额外的参数。不过,您可以将 size_t i 移到前面。另一种方法是不将 i 作为参数传递,而是将 + 1 添加到 return 值:

template<typename Arg>
constexpr std::size_t get_init_size(Arg&&) {
    return 1;
}

template<typename T, typename... Args>
constexpr std::size_t get_init_size(T&&, Args&&... args) {
    return get_init_size(args...) + 1;
}