gpt4 book ai didi

c++ - 如何找到模板函数接受的参数数量?

转载 作者:可可西里 更新时间:2023-11-01 17:53:23 26 4
gpt4 key购买 nike

我有以下类型特征:

template <class T>
struct Arity : Arity<decltype(&T::operator())> {};

template <class T, class R, class... Args>
struct Arity<R(T::*)(Args...)> {
static constexpr auto value = sizeof...(Args);
};

template <class T, class R, class... Args>
struct Arity<R(T::*)(Args...) const> {
static constexpr auto value = sizeof...(Args);
};

template <class R, class... Args>
struct Arity<R(*)(Args...)> {
static constexpr auto value = sizeof...(Args);
};

对于大多数用例,它可以很好地找到一个函数所接受的参数数量,但对于一个常见的情况却失败了:

auto l1 = [](int, double){};
Arity<decltype(l1)>::value; // works, 2

auto l2 = [](auto, auto){};
Arity<decltype(l2)>::value; // error: Reference to overloaded function could not be resolved; did you mean to call it?

我认为通常不可能对任何模板函数/operator() 进行这项工作,因为根据作为模板类型传递的类型/值,可以选择不同的重载,或者可能根本没有重载可用。此外,无法知道哪些有效类型和值可以作为模板参数传递。但是,我仍然希望这适用于采用 auto 参数的 lambda 的常见情况。有什么方法可以使它更健壮并覆盖采用自动参数的 lambda?

最佳答案

我想我在这里实现了一半的解决方案。最多只能使用固定数量的参数,但对于大多数应用程序来说,这应该不是问题。此外,它可能是高度可简化的,但我的大脑现在并没有进入棘手的 SFINAE。

template <
class, std::size_t N,
class = std::make_index_sequence<N>,
class = void_t<>
>
struct CanCall : std::false_type { };

template <class F, std::size_t N, std::size_t... Idx>
struct CanCall<
F, N,
std::index_sequence<Idx...>,
void_t<decltype(std::declval<F>()((Idx, std::declval<Any const&&>())...))>
> : std::true_type { };

CanCall<F, N>将返回是否F可以用 N 调用任意类型的参数。 Any辅助类型具有模板化的隐式转换运算符,允许它变形为任何所需的参数类型。

template <class F, std::size_t N = 0u, class = void>
struct Arity : Arity<F, N + 1u, void> { };

template <class F, std::size_t N>
struct Arity<F, N, std::enable_if_t<CanCall<F, N>::value>>
: std::integral_constant<std::size_t, N> { };

template <class F>
struct Arity<F, MAX_ARITY_PROBING, void>
: std::integral_constant<std::size_t, ARITY_VARIADIC> { };

Arity<F>只是检查是否 F可以用零,一,二...参数调用。第一次正面检查获胜。如果我们到达 MAX_ARITY_PROBING参数,Arity退出并假设函数是可变的,或者根本不是函数。

See it live on Coliru

关于c++ - 如何找到模板函数接受的参数数量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41556789/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com