【问题标题】:Expanding a lambda for each parameter of a parameter pack: Clang vs. GCC为参数包的每个参数扩展 lambda:Clang 与 GCC
【发布时间】:2015-03-31 17:38:22
【问题描述】:

此代码在 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 和许多人一样,是垃圾邮件发送者的受害者。您所在的页面提供了有关如何创建帐户的说明(发送电子邮件至监督者@...)。
  • 乍一看,代码假定语句末尾的未扩展参数包是错误的。

标签: c++11 lambda variadic-templates


【解决方案1】:

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>...
  );
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-22
    相关资源
    最近更新 更多