如何实现一个函数来调用任何模板化 lambda 函数?

问题描述 投票:0回答:1

我有一个

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

c++ templates lambda c++20 typename
1个回答
0
投票

您期望前 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...);
}

演示

© www.soinside.com 2019 - 2024. All rights reserved.