检测可调用对象是否为二进制(包括通用约束lambda)

时间:2016-10-19 12:30:04

标签: c++ lambda c++14 c++17 detection-idiom

我正在尝试检测可调用对象是否为二进制(即,如果其<a href="{{route('change_password'}}">Change Password</a> 有两个参数)。我想对lambdas执行此检查,包括通用lambdas 约束通用lambdas (例如,使用尾随operator()返回类型)

注意:这是重复"arity of a generic lambda"。我只关心检查泛型lambda是否是二进制的,并且我已经可以为无约束的通用lambdas 通用lambda做这个,它们不使用它们体内的参数

我目前的方法是应用Kris Jusiak's Boost.DI C++Now 2015 talk中描述的技术之一:std::enable_if_t。它基本上是一个可以隐式转换为任何其他类的类。

any_type

在定义struct any_type { template <typename T> constexpr operator T() const noexcept { return {}; } }; 之后,我使用detection idiom检查是否可以使用两个参数调用特定的可调用对象:

any_type

这种方法适用于非泛型和通用lambda ......

template<class T>
using is_binary_callable_impl = decltype(std::declval<T>()(any_type{}, any_type{}));

template <typename T>
using is_binary_callable = std::experimental::is_detected<is_binary_callable_impl, T>;

...但是当使用auto unary_nongeneric = [](int){}; auto unary_generic = [](auto){}; auto binary_nongeneric = [](int, float){}; auto binary_generic = [](auto, auto){}; static_assert(!is_binary_callable<decltype(unary_nongeneric)>{}); static_assert(!is_binary_callable<decltype(unary_generic)>{}); static_assert(is_binary_callable<decltype(binary_nongeneric)>{}); static_assert(is_binary_callable<decltype(binary_generic)>{}); 不支持的接口或lambda受约束的接口访问参数时,可怕失败:

any_type
  

错误:静态断言失败

auto binary_generic_constrained = [](auto, auto x) 
    -> std::enable_if_t<std::is_arithmetic<std::decay_t<decltype(x)>>{}> {};

// Fails!
static_assert(is_binary_callable<decltype(binary_generic_constrained)>{});
  

错误:'struct any_type'没有名为'something'的成员

The full code is on available here (on wandbox)

假设我在auto binary_generic_body = [](auto, auto x){ x.something(); }; // Compilation error! static_assert(is_binary_callable<decltype(binary_generic_constrained)>{}); 的正确轨道上,有没有办法忽略lambda的返回类型和lambda的身体?更详细:

  • 是否可以检查通用约束lambda是否为二进制?

  • 是否可以检查尝试访问其参数的特定成员的通用lambda是否为二进制?

否则,还有其他方法可以在这里发挥作用吗?

0 个答案:

没有答案