首页 文章

英特尔编译器无法使用多个参数编译可变参数lambda捕获

提问于
浏览
2

这是我能够提出的最小例子:

#include <utility>
template<class CB, class... ARGS>
void call_lam(CB&& cb, ARGS&&... args) {
     auto lam = [&args...](auto&& callee) { 
                callee(std::forward<ARGS>(args)...);
     };
     lam(cb);
}

void exec(unsigned, int);

void foo() {
  unsigned x = 25;
  int y = 0;
  call_lam(exec, x, y);
}

以上示例使用CLang和gcc进行编译,但是使用icc 17.0进行编译(如https://godbolt.org/g/tzMY6K所示) . 错误如下:

/ usr / include / c /5/bits/move.h(89):错误:静态断言失败,“模板参数替换_Tp是左值引用类型”static_assert(!std :: is_lvalue_reference <_Tp> :: value, “模板参数”^检测到:“_Tp && std :: forward <_Tp>(std :: remove_reference <_Tp> :: type &&)[with _Tp = unsigned int&]”在“”函数实例化的第5行实例化“lambda [](auto &&) - > auto [with = void(&)(unsigned int,int)]”“void”call_lam的实例化“第7行”(CB &&,ARGS && ...)[与CB = void(&)(unsigned int,int),ARGS =]“第15行”“编译中止(代码2)编译器退出,结果代码为2

玩这个例子,我发现:

  • 必须将不同类型作为 exec 的参数 . 当使用两个整数或一个参数时,错误就会消失

  • 通过用其他东西替换类型(例如, std::string )并将参数传递方式更改为 execconst& ),可以将错误报告为其他内容,称“无法匹配 std::move 的重载” . 此时,它也会在icc16上失败 . 这是稍微修改过的代码:https://godbolt.org/g/qHrU6P

如果代码格式正确(我相信它是),除了用自定义函子替换lambda(我不想这样做,因为我不想通过元组手动捕获带有正确引用的可变数量的参数)有没有人在这看到任何变通办法?

1 回答

  • 0

    我认为以下代码将满足您的解决方案要求:

    #include <utility>
    #include <iostream>
    #include <tuple>
    
    template<class CB, class... ARGS>
    void call_lam(CB&& cb, ARGS&&... args) {
         auto lam = [](auto&&... args2){
             return [&args2...](auto&& callee) { 
                    callee(std::forward<std::tuple_element_t<0, std::decay_t<decltype(args2)>>>(std::get<0>(args2))...);
             };}(std::forward_as_tuple(std::forward<ARGS>(args))...);
         lam(cb);
    }
    
    struct A {
        A() {
            std::cout << "A()" << std::endl;
        }
        A(const A&) {
            std::cout << "A(const A&)" << std::endl;
        }
        A(A&&) {
            std::cout << "A(A&&)" << std::endl;
        }
    };
    
    void exec(A &, A) {
    }
    
    int main() {
      A a;
      call_lam(exec, a, A());
    }
    

相关问题