Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将变量函数模板的每个参数传递给返回void的函数_C++_Templates_C++11_Variadic Templates - Fatal编程技术网

C++ 将变量函数模板的每个参数传递给返回void的函数

C++ 将变量函数模板的每个参数传递给返回void的函数,c++,templates,c++11,variadic-templates,C++,Templates,C++11,Variadic Templates,根据找到的配方,我写了以下内容: void printInt(int a) {std::cout << a << std::endl;} template <typename... Args> void f(const Args &... args) { auto temp = {(printInt(args), void(), 0)...}; auto a = temp; temp = a; } 这个问题在引用的帖子中被问到,但没

根据找到的配方,我写了以下内容:

void printInt(int a) {std::cout << a << std::endl;}

template <typename... Args>
void f(const Args &... args) {
    auto temp = {(printInt(args), void(), 0)...};
    auto a = temp; temp = a;
}
这个问题在引用的帖子中被问到,但没有得到任何回答

  • 此语法意味着,
    temp
    std::initializer\u list
    填充零,这是由于逗号运算符规则(将计算所有表达式,但只使用最后一个表达式,因此,将为每个参数调用函数
    printInt
    ,并为每个参数将0放入初始值设定项列表)
  • N4296 5.19/1

    由逗号分隔的一对表达式从左到右求值; 左边的表达式是一个废弃的值表达式(第5条)。87 每一个值的计算和副作用都与左 表达式在每次值计算和副作用之前排序 与正确的表达式关联。结果的类型和值 是右操作数的类型和值;结果是一样的 值类别作为其右操作数,如果它是右操作数,则为位字段 操作数是一个值和一个位字段。如果权利的价值 操作数是临时的(12.2),结果是临时的

    ()
    用于包扩展,因此,
    ..
    将应用于full expression,
    void()
    用于保护构造不受类重载运算符的影响(感谢Quentin),您还可以使用以下

    {((void)printInt(args), 0)...};
    
    而且,使用它会更好

    {0, ((void)printInt(args), 0)...};
    
    对于
    初始值设定项列表
    中的至少一个元素(因此您可以无参数调用
    f

  • 您可以使用
    (void)temp要标记未使用的变量,请参阅以下详细信息:

  • 这个答案太简洁了。我不明白1到底发生了什么:圆括号和
    void()
    的作用是什么?另外,对于2,为什么编译器不抱怨语句对
    (void)temp没有影响
    void()
    是用来保护构造不受类重载
    操作符的影响,
    @永远是迂腐的,可能有;)
    printInt
    被称为unqualified,您不能保证
    Args
    都是
    int
    s,因此您可能会通过ADL发现一些奇怪的东西:P(解决这个问题的方法可能是通过一个限定的调用来抑制ADL。)@MeirGoldenberg当然!类可以重载
    运算符、
    、逗号运算符。假设
    printInt(arg)
    返回
    Foo
    ,那么如果存在重载的
    条形运算符(Foo,int)
    ,它将被
    (printInt(args),0)
    调用。如果对于每个可能的
    Foo
    来说
    Bar
    并不总是相同的类型,那么您最终会尝试将不同类型的对象填充到相同的
    std::initializer\u列表中,这是一个错误。@MeirGoldenberg现在,解决方案:
    void()
    并不是一个完全空的表达式强制转换(没有空表达式),但结果是一样的:您获得类型为
    void
    的表达式。而且不可能构造一个重载的
    操作符(Foo,void)
    操作符(void,int)
    。因此,通过插入
    void
    表达式,您可以确定使用的是内置的逗号运算符。
    {((void)printInt(args), 0)...};
    
    {0, ((void)printInt(args), 0)...};