我有一个
value_t
将值包装为类型:
template <auto _v>
struct value_t { static constexpr auto value = _v; };
我可以使用
take_off
来提取类型和值:
template <typename T>
struct take_off { using result = T; };
template <auto _v>
struct take_off<value_t<_v>> { static constexpr auto result = _v; };
现在我想通过调用
invoke
(c++20 或 23)来调用具有任何模板参数和函数参数的任何 lambda 函数:
auto test_fn = []<typename T, typename T2, T... Vs>(int a, int b){
(..., (std::cout << (T2)Vs << std::endl));
std::cout << a << b << std::endl;
};
// template <typename...>
// auto invoke(test_fn, ...)
invoke<int, double, value_t<1>, value_t<2>, value_t<5>>(test_fn, 1, 2);
我的
invoke
实现是:
template <typename... Ts>
decltype(auto) invoke(auto _fn, auto... _args) {
using ret_type = decltype(_fn.template operator()<take_off<Ts>::result...>(_args...));
if constexpr (std::is_void_v<ret_type>) {
_fn.template operator()<take_off<Ts>::result...>(_args...);
return;
} else {
return _fn.template operator()<take_off<Ts>::result...>(_args...);
}
}
它在 MSVC 上运行良好。 但是用clang编译的时候却出现了错误:
error: missing 'typename' prior to dependent type name `take_off<Ts>::result`
如果我使用 invoke
代替,
auto
将不再适用于 typename take_off<Ts>::result
模板参数。
那么有没有办法实现这个
invoke
?
您期望前 2 个
typename
take_off<Ts>::result
。
您可以将代码重写为
template <typename T1, typename T2, typename... Ts>
decltype(auto) invoke(auto _fn, auto... _args) {
return _fn.template operator()<
typename take_off<T1>::result,
typename take_off<T2>::result,
take_off<Ts>::result...>(_args...);
}