【问题标题】:Doesn't instance call function to variadic template不实例调用函数到可变参数模板
【发布时间】:2021-11-18 08:27:41
【问题描述】:

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

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)

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

【问题讨论】:

    标签: c++ templates c++17


    【解决方案1】:

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

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

    看到它在行动here

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

    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;
    }
    

    【讨论】:

    • 你说得对,但我也很感兴趣为什么它不起作用
    猜你喜欢
    • 2021-10-01
    • 1970-01-01
    • 2014-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多