微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐