我正在尝试检测可调用对象是否为二进制(即,如果其<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是否为二进制?
否则,还有其他方法可以在这里发挥作用吗?