gpt4 book ai didi

c++ - 检查一个类型是一个包含泛型 lambda 的仿函数

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:10:34 25 4
gpt4 key购买 nike

我可以写一个 trait 元函数来判断一个类型是不是仿函数吗?有大量代码可以使用 decltype(&T::operator()) 的 SFINAE 检查仿函数,例如,

template<class T>
struct is_functor {
template<class F>
static auto test(decltype(&F::operator())) -> std::true_type;
template<class F>
static auto test(...) -> std::false_type;
static constexpr bool value = decltype(test<T>(0))::value;
};

但是,这不适用于通用 lambda,因为通用 lambda的 operator() 是一个模板函数。

有一些针对通用 lambda 版本的有限情况的代码对通用 lambda 的参数类型做了一些限制。例如,如果 lambda 表达式包含任何对 int 类型无效的表达式(例如成员访问操作),则此处的答案 ( https://stackoverflow.com/a/5117641/2580815) 将不起作用。

我不需要任何通用性。事实上,我只需要知道一个类型可以是一个只接受一个参数的仿函数。

如何实现我的 is_functor

用例:

我正在尝试验证给定参数是否为模板函数的仿函数,也就是说,我想要一些重载的模板函数,例如:

template<class F, class = enable_if_t<is_functor<std::decay_t<F>>::value>>
auto make_func(F &&f) { return std::forward<F>(f); }
template<class F, class = enable_if_t<!is_functor<std::decay_t<F>>::value>>
auto make_func(F &&f) { return [f=std::forward<F>(f)] (auto&&) { return f; }; }

最佳答案

没有合适的方法来做到这一点(至少在我们得到静态反射之前是这样)。您能做的最好的事情就是检查一个对象是否具有一定的置信度可调用:

  1. 尝试获取它的 operator() 地址。如果失败,则该对象可能不可调用,或者它的operator() 可能被重载/模板化。

  2. 尝试使用为常用函数提供接口(interface)的虚拟 any_type 实例调用对象。这可能会帮助您推断其数量。

  3. 如果一切都失败了,强制用户以某种方式帮助扣除元数或手动指定元数。

解决这个问题的一种方法是使用一组 deduced_arity 标签:

namespace deduced_arity
{
template <std::size_t TS>
struct deducible_t : std::integral_constant<std::size_t, TS>
{
};

struct undeducible_t
{
};

constexpr undeducible_t undeducible{};
constexpr deducible_t<1> unary{};
}

您还需要某种function_traits 实现,它会静态地告诉您函数对象 的确切元数。这可以是 found in Boost .

那你还需要an implementation of any_type .

之后,您可以使用类似以下类型特征的东西来检查函数对象是否可能被重载,使用检测习惯用法:

template <typename T>
using is_not_overloaded_impl = decltype(&T::operator());

template <typename T>
using is_not_overloaded =
std::experimental::is_detected<is_not_overloaded_impl, T>;

然后您可以使用一系列 if constexpr(...) (或任何其他编译时分支机制) 来做出很好的猜测 - 示例:

if constexpr(is_not_overloaded<T>{})
{
// use `function_traits` here
}
else if constexpr(std::is_callable<T(any_type)>{})
{
return deduced_arity::unary;
}
else if constexpr(/* user manually marked arity */)
{
/* deal with user-defined deduction helpers */
}
else
{
return deduced_arity::undeducible;
}

关于c++ - 检查一个类型是一个包含泛型 lambda 的仿函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42294333/

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