将参数包扩展到具有折叠表达式的lambda -GCC与Clang
Expanding parameter pack into lambda with fold expression - gcc vs clang
考虑以下代码段:
template <typename TF>
void post(TF){ }
template <typename... TFs>
struct funcs : TFs...
{
funcs(TFs... fs) : TFs{fs}... { }
void call()
{
(post([&]{ static_cast<TFs&>(*this)(); }), ...);
}
};
clang 3.8 成功编译了代码。
g 7.0 无法与以下错误进行编译:
prog.cc: In lambda function:
prog.cc:10:43: error: parameter packs not expanded with '...':
(post([&]{ static_cast<TFs&>(*this)(); }), ...);
~~~~~~~~~~~~~~~~~~~~~~~~^~
prog.cc:10:43: note: 'TFs'
prog.cc: In member function 'void funcs<TFs>::call()':
prog.cc:10:13: error: operand of fold expression has no unexpanded parameter packs
(post([&]{ static_cast<TFs&>(*this)(); }), ...);
~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
删除post
调用,lambda使G 编译折叠表达式。
是标准以某种方式禁止lambdas,fold表达式和模板函数之间的这种相互作用,还是这是GCC错误?
这是一个旧的GCC错误。这是GCC模板处理要比MSVC差的少数情况之一。羞耻的海湾合作委员会。可耻。
有时有效的解决方法是使用标签和包装扩展。
template<class T>struct tag_t{using type=T; constexpr tag_t(){};};
template<class T>constexpr tag_t<T> tag{};
template<class Tag>using type_t=typename Tag::type;
#define TAG2TYPE(...) type_t<decltype(__VA_ARGS__)>
// takes args...
// returns a function object that takes a function object f
// and invokes f, each time passing it one of the args...
template<class...Args>
auto expand( Args&&...args ) {
return [&](auto&& f)->decltype(auto) {
using discard=int[];
(void)discard{0,(void(
f( std::forward<Args>(args) )
),0)...};
};
}
template <typename TF>
void post(TF){ }
template <typename... TFs>
struct funcs : TFs...
{
funcs(TFs... fs) : TFs{fs}... { }
void call() {
expand( tag<TFs>... )
([&](auto tag){
post(static_cast< TAG2TYPE(tag)& >(*this)());
});
}
};
我们每次通过通过Lambda来避免在Lambda的末端进行扩展。相反,我们进行了一组参数,并将其扩展为一组lambda调用。
lambda将类型作为标签传递,然后将其转换回类型。
实例示例
如果您通过了临时性,请勿存储expand
的返回类型。
这是一个众所周知的G 错误(#47226),在... 2011年报告。
相关文章:
- 为什么lambda在clang上崩溃而不是在gcc上崩溃
- Visual C++: MSVC vs. GCC+CLANG: 处理 lambda 捕获类成员变量,正确的方法是什么?
- 为什么 GCC 和 clang 之间编译的 c++17 lambda 存在差异?
- 修改嵌套 lambda 中捕获的参数:gcc 与 clang?
- 在折叠表达式中扩展参数包作为 lambda 捕获的一部分 - gcc 与 clang
- GCC 6.x警告有关Lambda可见性
- 与lambda一起使用虚拟继承在初始化列表中捕获此问题的GCC错误
- 在折叠表达式中使用 lambda 时"Uninitialized captured reference"错误 - clang vs gcc
- 为什么将 lambda 用于非类型模板参数时 gcc 失败?
- 如何在 c++/gcc 中获取 lambda 函数名称?
- 如何获取在 gcc 5+ 上不起作用的 lambda 函数
- 使用 lambda 的错误 gcc 行为
- 将参数包扩展到具有折叠表达式的lambda -GCC与Clang
- 从值捕获的变量分配到lambda参数时,GCC编译器分割故障
- 如果对QObject::connect()使用lambda函数,则使用gcc编译失败
- 可能的 gcc 错误与 C++14 多态 lambda
- 在非“constexpr”上下文中的“constexpr”函数中使用lambda:clang vs gcc
- 与GCC/MSVC中的lambda转换构造函数不一致
- 为什么不允许使用=和this的lambda(但GCC接受)
- GCC在lambda函数中通过引用错误地捕获全局变量