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

相关文章

文章浏览阅读315次。之前用C语言编过链表,这几天突然想用C+...
文章浏览阅读219次。碰到问题就要记录下来,防止遗忘吧。文章...
文章浏览阅读1.8k次,点赞11次,收藏37次。因为自己对决策树...
文章浏览阅读492次。C++ 设计模式之策略模式
文章浏览阅读683次。我也算是个C++的小白,对于C++中的谓语我...
文章浏览阅读225次。又看了一遍操作符的东西,感觉之前对操作...