gpt4 book ai didi

c++11 - 为参数包 : Clang vs. GCC 的每个参数扩展一个 lambda

转载 作者:行者123 更新时间:2023-12-04 08:48:33 26 4
gpt4 key购买 nike

此代码在 Clang 3.5 中运行良好:

#include <iostream>
#include <string>

void callFuncs() {}

template<typename Func, typename ...Funcs>
void callFuncs(const Func &func, const Funcs &...funcs)
{
func();
callFuncs(funcs...);
}

template<typename ...Types>
void callPrintFuncs()
{
callFuncs(([] { std::cout << Types() << std::endl; })...);
}

int main()
{
callPrintFuncs<int, float, double, std::string>();
}

但是,在 GCC 4.9 中,我收到以下错误:
test.cpp: In lambda function:
test.cpp:16:54: error: parameter packs not expanded with '...':
callFuncs(([] { std::cout << Types() << std::endl; })...);
^
test.cpp:16:54: note: 'Types'
test.cpp: In function 'void callPrintFuncs()':
test.cpp:16:58: error: expansion pattern '<lambda>' contains no argument packs
callFuncs(([] { std::cout << Types() << std::endl; })...);

那么,哪个编译器有错误,Clang 还是 GCC? Clang 的行为至少对我来说是最有意义的。

最佳答案

gcc 在这里坏了。标准中有针对未扩展参数包的规定,但是上面的参数包是扩展的。

它在它所在的最里面的语句结束后扩展,但标准不要求在每个语句的末尾扩展参数包。

gcc 出错的事实是可以理解的;天真地,您会认为参数包只能在一个语句内,并且在语句末尾无法展开是致命的。但是 lambda 表达式允许您在语句中嵌套语句。

一般的解决方法是传入一个 lambda 并传入一个“标签”类型给它。

template<class T>struct tag_t{using type=T;};
template<class Tag>using type_t=typename Tag::type;

template<typename Func, typename ...Ts>
void callOnEachOf(Func&&func, Ts&&...ts)
{
using discard=int[];
(void)discard{0,((void)(
func(std::forward<Ts>(ts))
),0)...};
}
template<typename ...Types>
void callPrintFuncs()
{
callOnEachOf(
[](auto tag){
using Type=type_t<decltype(tag)>;
std::cout << Type() << std::endl;
},
tag_t<Types>...
);
}

关于c++11 - 为参数包 : Clang vs. GCC 的每个参数扩展一个 lambda,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28266489/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com