处理“std::size_t”类型的可变参数函数参数

nir*_*n90 1 c++ variadic-functions variadic-templates c++17 c++20

我正在尝试掌握可变函数/模板参数的窍门。但是,在下面的两个函数中,我很困惑为什么SumIndices不能编译(我收到编译器错误“expansion pattern \xe2\x80\x98std::size_t\xe2\x80\x99 {aka \xe2\x80\x98long unsigned int\xe2\x80\x99} 不包含参数包”)而包含SumValues

\n
template <typename ...t_data_type>\nconstexpr auto SumValues(t_data_type ..._values) { \n  return (_values + ...); \n}\n\nconstexpr auto SumIndices(std::size_t ..._indices) { \n  return (_indices + ...); \n}\n
Run Code Online (Sandbox Code Playgroud)\n

如果有人能为我澄清这个困惑,我将不胜感激!

\n

Ang*_*ros 5

在第一种情况下,您有参数 pack。在第二种情况下,你有来自 C 的可变参数函数。

可变参数模板允许您将不同类型安全地传递到函数中。打印示例:

// Create this function to terminate argument depended lookup
void PrintValues(std::ostream&){}
template<typename TFirstArg, typename ...TArgs>
void PrintValues(std::ostream& output, const TFirstArg& arg, const TArgs... other_args){
   // Recursive call to another function which has N-1 args
   // If other_args are empty, it would call `void PrintValues(std::ostream&)`
   // If they are non empty, it would call another instantiation of this template
   PrintValues(output << arg, other_args...);
}
Run Code Online (Sandbox Code Playgroud)

这可以这样称呼:

PrintValues(std::cout, 5LL, 7.59, "Hello world", std::string{"bingo"});
Run Code Online (Sandbox Code Playgroud)

使用可变参数,你可以这样做:

void PrintFewNumbers(size_t number_of_args, ...)
{
    va_list args;
    va_start(args, number_of_args);
    for (size_t idx_of_arg, idx_of_arg < number_of_args; ++idx_of_arg){
        size_t current_arg = va_arg(args, size_t);
        std::cout << current_arg;
    }
    va_end(args);
}
Run Code Online (Sandbox Code Playgroud)

您可以使用以下方式调用它:

PrintFewNumbers(0);
PrintFewNumbers(5, 1,2,3,4,5);
Run Code Online (Sandbox Code Playgroud)

您应该更喜欢可变参数模板而不是可变参数参数,因为它们是类型安全的。然而,它们并不总是可用。