这是我能够提出的最小例子:
#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
)并将参数传递方式更改为exec
(const&
),可以将错误报告为其他内容,称“无法匹配std::move
的重载” . 此时,它也会在icc16上失败 . 这是稍微修改过的代码:https://godbolt.org/g/qHrU6P
如果代码格式正确(我相信它是),除了用自定义函子替换lambda(我不想这样做,因为我不想通过元组手动捕获带有正确引用的可变数量的参数)有没有人在这看到任何变通办法?
1 回答
我认为以下代码将满足您的解决方案要求: