用于测试任意方法是否存在的 std::is_invocable 语法(不仅是 operator()) [英] std::is_invocable syntax for testing existence of an arbitrary method (not only operator())

查看:29
本文介绍了用于测试任意方法是否存在的 std::is_invocable 语法(不仅是 operator())的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 C++17 中,我知道我可以写:

In C++17 I know that I can write:

#include <type_traits>

struct A
{
  size_t operator()(double x) const { return 1; };
};

int main()
{
  static_assert(std::is_invocable_r_v<size_t, A, double>);  
}

但是现在我想使用 std::is_invocable 来测试任意方法的存在(这里是 size(double) 方法):

However now I want to use std::is_invocable to test the existence of an arbitrary method (here the size(double) method):

#include <type_traits>

struct A
{
  size_t size(double x) const { return 1; };
};

int main()
{
   static_assert(std::is_invocable_r_v<size_t, ???, double>);  
}

问题是如何填写???"让它发挥作用?

推荐答案

使用检测成语:

template <typename T, typename... Args>
using call_size_t = decltype(std::declval<T>().size(std::declval<Args>()...);

template <typename R, typename T, typename... Args>
using is_size_callable = is_detected_convertible<R, call_size_t, T, Args...>;

static_assert(is_size_callable<size_t, A, double>::value);

这有利于与重载、模板或采用默认参数的成员函数 size 一起使用.

This has the benefit of working with member functions size that are overloaded, templates, or take default arguments as well.

在带有概念的 C++20 中:

In C++20 with concepts:

template <typename T, typename R, typename... Args>
concept is_size_callable = requires (T t, Args... args) {
    { t.size(std::forward<Args>(args)...) } -> std::convertible_to<R>;
};

static_assert(is_size_callable<A, size_t, double>);

我翻转了参数以将 T 放在首位,因为这将允许 type-constraint 语法:

I flipped the arguments to put T first, since this would allow the type-constraint syntax:

template <is_size_callable<size_t, double> T>
void foo(T );

foo(A{});

这篇关于用于测试任意方法是否存在的 std::is_invocable 语法(不仅是 operator())的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆