给出(减少)检测惯用语的实现
namespace type_traits
{
template<typename... Ts>
using void_t = void;
namespace detail
{
template<typename, template<typename...> class, typename...>
struct is_detected : std::false_type {};
template<template<class...> class Operation, typename... Arguments>
struct is_detected<void_t<Operation<Arguments...>>, Operation, Arguments...> : std::true_type {};
}
template<template<class...> class Operation, typename... Arguments>
using is_detected = detail::is_detected<void_t<>, Operation, Arguments...>;
template<template<class...> class Operation, typename... Arguments>
constexpr bool is_detected_v = detail::is_detected<void_t<>, Operation, Arguments...>::value;
}
我们可以轻松地检查类是否foo
包含成员函数bar
struct foo {
int const& bar(int&&) { return 0; }
};
template<class T>
using bar_t = decltype(std::declval<T>().bar(0));
int main()
{
static_assert(type_traits::is_detected_v<bar_t, foo>, "not detected");
return 0;
}
但是,如您所见,我们无法检测到foo::bar
的参数类型为int&&
。检测成功,原因0
可以传递给foo::bar
。我知道有很多选项可以检查(成员)函数的确切签名。但我想知道,是否有可能修改此检测工具包以检测该foo::bar
参数类型是否为int&&
。
[我已经创建了这个示例的现场演示。]
template<class T, typename... Arguments>
using bar_t = std::conditional_t<
true,
decltype(std::declval<T>().bar(std::declval<Arguments>()...)),
std::integral_constant<
decltype(std::declval<T>().bar(std::declval<Arguments>()...)) (T::*)(Arguments...),
&T::bar
>
>;
注意,这bar_t
将是bar
调用的返回类型。这样,我们与工具包保持一致。我们可以通过以下方式检测存在
static_assert(type_traits::is_detected_v<bar_t, foo, int&&>, "not detected");
但是,尽管此解决方案完全符合我的预期,但我讨厌为每种要检测的方法编写“非常复杂的代码”。我问了一个针对这个问题的新问题。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句