在 MSVC19 中的 lambda 中捕获可变参数包的问题
Issue with capturing of a variadic pack inside of lambda in MSVC19
我正在尝试编写一个 SFINAE 友好的 bind_back
函数,类似于 C++20 的 std::bind_front
。但是,MSVC 的代码似乎存在一些问题。
我设法将问题最小化为以下代码片段:
auto bind_back(auto f, auto ...back_args) {
return [=](auto ...front_args)
requires requires { f(front_args..., back_args...); } {
return f(front_args..., back_args...);
};
}
int main() {
auto h = bind_back([]{});
h();
}
https://godbolt.org/z/3bc8GaqTv
编译此片段时,出现以下错误:
<source>(10): error C2672: 'operator __surrogate_func': no matching overloaded function found
<source>(10): error C2893: Failed to specialize function template 'decltype(auto) bind_back::<lambda_1>::operator ()(_T1...) const'
<source>(5): note: see declaration of 'bind_back::<lambda_1>::operator ()'
<source>(10): note: With the following template arguments:
<source>(10): note: '_T1={}'
看来Clang和GCC编译这段代码都没有问题
我的问题是:
- 这是有效的 C++20,对吧?
- 是否有针对 MSVC 的解决方法,以便我可以使用这些类型的构造? (即使其对 SFINAE 友好)。
- this is valid C++20, right?
是的,在 C++20 中 lambda 可以被 requires 子句约束,所以它是 well-formed。
- is there a work around for MSVC such that I can use these kind of constructs? (i.e. making it SFINAE-friendly).
MSVC 似乎在处理 requires 子句方面存在一些问题。相反,您可以使用 std::invocable
:
#include <concepts>
template<class F, class... BoundArgs>
auto bind_back(F f, BoundArgs... bound_args) {
return [=]<class... CallArgs>(CallArgs... call_args)
requires std::invocable<F&, CallArgs&..., BoundArgs&...> {
return f(call_args..., bound_args...);
};
}
值得注意的是,P2387 还引入了 std::bind_back
以支持 user-defined 作用域适配器的管道运算符。
我正在尝试编写一个 SFINAE 友好的 bind_back
函数,类似于 C++20 的 std::bind_front
。但是,MSVC 的代码似乎存在一些问题。
我设法将问题最小化为以下代码片段:
auto bind_back(auto f, auto ...back_args) {
return [=](auto ...front_args)
requires requires { f(front_args..., back_args...); } {
return f(front_args..., back_args...);
};
}
int main() {
auto h = bind_back([]{});
h();
}
https://godbolt.org/z/3bc8GaqTv
编译此片段时,出现以下错误:
<source>(10): error C2672: 'operator __surrogate_func': no matching overloaded function found
<source>(10): error C2893: Failed to specialize function template 'decltype(auto) bind_back::<lambda_1>::operator ()(_T1...) const'
<source>(5): note: see declaration of 'bind_back::<lambda_1>::operator ()'
<source>(10): note: With the following template arguments:
<source>(10): note: '_T1={}'
看来Clang和GCC编译这段代码都没有问题
我的问题是:
- 这是有效的 C++20,对吧?
- 是否有针对 MSVC 的解决方法,以便我可以使用这些类型的构造? (即使其对 SFINAE 友好)。
- this is valid C++20, right?
是的,在 C++20 中 lambda 可以被 requires 子句约束,所以它是 well-formed。
- is there a work around for MSVC such that I can use these kind of constructs? (i.e. making it SFINAE-friendly).
MSVC 似乎在处理 requires 子句方面存在一些问题。相反,您可以使用 std::invocable
:
#include <concepts>
template<class F, class... BoundArgs>
auto bind_back(F f, BoundArgs... bound_args) {
return [=]<class... CallArgs>(CallArgs... call_args)
requires std::invocable<F&, CallArgs&..., BoundArgs&...> {
return f(call_args..., bound_args...);
};
}
值得注意的是,P2387 还引入了 std::bind_back
以支持 user-defined 作用域适配器的管道运算符。