c – 没有typedef的Variadic扩展器

前端之家收集整理的这篇文章主要介绍了c – 没有typedef的Variadic扩展器前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
通常用于执行可变参数扩展的一个技巧是使用未组合的数组typedef与逗号运算符组合,如下所示:
#include <iostream>

template<typename... Ts>
void expander(Ts&&... ts)
{
    using expand = int[];
    (void)expand{0,(std::forward<Ts>(ts)(),0)...};
}
void f()
{
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}
int main()
{
    expander(f,f);
}

Live on Coliru

我们可以在不引入typedef的情况下这样做吗?如果我直接尝试

(void)int[]{0,0)...};

gcc / clang吐了出来

error: expected primary-expression before ‘int’

如果我尝试括号,代码编译但我相信它是非标准的:

warning: ISO C++ forbids compound-literals [-Wpedantic]

解决方法

在这个表达中
(void)int[]{0,0)...};

您正在尝试使用功能表示法转换来创建临时数组.这是行不通的,因为该语言只允许函数表示法与simple-type-specifier或typename-specifier一起使用.

[expr.type.conv]/3

Similarly,a simple-type-specifier or typename-specifier followed by a braced-init-list creates a temporary object of the specified type direct-list-initialized (8.5.4) with the specified braced-init-list,and its value is that temporary object as a prvalue.

如果你在[dcl.type.simple]下查找simple-type-specifier的定义,它不包含带数组括号的任何东西.事实上,它甚至不包含任何超过一个单词的内容.这就是编写int(1)有效的原因,但是signed int(1)不是.

因此,使用C 11/14,您需要一个typedef或声明一个数组变量.但是,使用C 1z编译器,您可以使用折叠表达式并避免两者

template<typename... Ts>
void expander(Ts&&... ts)
{
    (void(std::forward<Ts>(ts)()),...);
}

Live demo

原文链接:https://www.f2er.com/c/117408.html

猜你在找的C&C++相关文章