计算泛型 lambda 中的参数数量

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

我想创建一个函数来计算通用 lambda 函数中的参数数量。所以用户“yuri kilochek”有一个很好的解决方案计算 lambda 中的参数数量,但它不适用于采用引用类型的函数:

#include <iostream>
#include <utility>
#include <type_traits>


struct any_argument {
    template <typename T>
    operator T&&() const;
};


template <typename Lambda, typename Is, typename = void>
struct can_accept_impl
: std::false_type
{};

template <typename Lambda, std::size_t ...Is>
struct can_accept_impl<Lambda, std::index_sequence<Is...>, 
                       decltype(std::declval<Lambda>()(((void)Is, any_argument{})...), void())>
: std::true_type
{};

template <typename Lambda, std::size_t N>
struct can_accept
: can_accept_impl<Lambda, std::make_index_sequence<N>>
{};


template <typename Lambda, std::size_t Max, std::size_t N, typename = void>
struct lambda_details_impl
: lambda_details_impl<Lambda, Max, N - 1>
{};

template <typename Lambda, std::size_t Max, std::size_t N>
struct lambda_details_impl<Lambda, Max, N, std::enable_if_t<can_accept<Lambda, N>::value>>
{
    static constexpr bool is_variadic = (N == Max);
    static constexpr std::size_t argument_count = N;
};

template <typename Lambda, std::size_t Max = 50>
struct lambda_details
: lambda_details_impl<Lambda, Max, Max>
{};


int main()
{
    auto lambda0 = []() {};
    auto lambda1 = [](int a) {};
    auto lambda2 = [](int a, auto b) {};
    auto lambda3 = [](int a, auto b, char = 'a') {};
    auto lambda4 = [](int a, auto b, char = 'a', auto...) {};
    auto lambda5 = [](int a, auto& b){};

    std::cout << lambda_details<decltype(lambda0)>::is_variadic << " " << lambda_details<decltype(lambda0)>::argument_count << "\n"; // 0 0
    std::cout << lambda_details<decltype(lambda1)>::is_variadic << " " << lambda_details<decltype(lambda1)>::argument_count << "\n"; // 0 1
    std::cout << lambda_details<decltype(lambda2)>::is_variadic << " " << lambda_details<decltype(lambda2)>::argument_count << "\n"; // 0 2
    std::cout << lambda_details<decltype(lambda3)>::is_variadic << " " << lambda_details<decltype(lambda3)>::argument_count << "\n"; // 0 3
    std::cout << lambda_details<decltype(lambda4)>::is_variadic << " " << lambda_details<decltype(lambda4)>::argument_count << "\n"; // 1 50
    std::cout << lambda_details<decltype(lambda5)>::is_variadic << " " << lambda_details<decltype(lambda5)>::argument_count << "\n"; // 1 50
}

这是结果https://godbolt.org/z/35envxjfz

我觉得只需对代码进行微小的更改即可使其工作,但我对模板元编程相对较新。如何实现我想要的?

谢谢!

c++ templates lambda template-meta-programming
1个回答
0
投票

由于您传递了

any_argument{}
,即右值无法绑定到左值引用,因此编译失败。

简单的解决方法是传入

any_argument
的左值引用,例如

template <typename Lambda, std::size_t ...Is>
struct can_accept_impl<Lambda, std::index_sequence<Is...>, 
                       decltype(std::declval<Lambda>()((
                         (void)Is, std::declval<any_argument&>())...), void())>
: std::true_type
{};
© www.soinside.com 2019 - 2024. All rights reserved.