我正在考虑对C ++检测习惯用法提供标准库支持的建议。它是一种类似特征的元函数,用于确定类型是T
具有类型成员T::type
还是具有特定签名的成员函数,例如:
#include <iostream>
template<class...>
using void_t = void;
template<class, template<class> class, class = void_t<>>
struct detect : std::false_type { };
template<class T, template<class> class Operation>
struct detect<T, Operation, void_t<Operation<T>>> : std::true_type { };
template<class T>
using bar_t = decltype(std::declval<T>().bar());
template<class T>
using bar_int_t = decltype(std::declval<T>().bar(0));
template<class T>
using bar_string_t = decltype(std::declval<T>().bar(""));
struct foo
{
int bar() { return 0; }
int bar(int) { return 0; }
};
int main()
{
std::cout << detect<foo, bar_t>{} << std::endl;
std::cout << detect<foo, bar_int_t>{} << std::endl;
std::cout << detect<foo, bar_string_t>{} << std::endl;
return 0;
}
上面的代码产生了预期的输出
1
1
0
您可以播放现场演示。现在,我想测试一个类型T
是否具有带有特定签名的构造函数,例如T::T(U)
,另一个类型U
。可以使用检测惯用语来做到这一点吗?
修改detect
类以允许可变参数:
template <typename...>
using void_t = void;
template <typename AlwaysVoid, template <typename...> class Operation, typename... Args>
struct detect_impl : std::false_type { };
template <template <typename...> class Operation, typename... Args>
struct detect_impl<void_t<Operation<Args...>>, Operation, Args...> : std::true_type { };
添加一个对空类型进行硬编码的别名:
template <template <typename...> class Operation, typename... Args>
using detect = detect_impl<void, Operation, Args...>;
// ~~~^
写一个检测器:
template <typename T, typename... Us>
using has_constructor = decltype(T(std::declval<Us>()...));
测试您的课程:
static_assert(detect<has_constructor, foo, foo>{}, "!");
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句