在我的代码中,我需要测试给模板的类型是否是指针——它是否智能。根据 boost 的说法,没有可靠和通用的方法来做到这一点(见这里)——或者有吗?
到目前为止,我检查了以下内容:
- - 答:可以
T
转换为void*
? - B:
T
有get()
方法吗? - C:
T
有一个类型叫element_type
? - D:是否
get()
返回一个element_type*
?
如果 (A || B && C && D),那么我的结论是我的类型必须是某种指针。
这是模板:
template <typename T>
class is_pointer_type
{
typedef struct { char array[1]; } yes;
typedef struct { char array[2]; } no;
template <typename C> static yes test_g(decltype(&C::get));
template <typename C> static no test_g(...);
template <typename C> static yes test_e(typename C::element_type*);
template <typename C> static no test_e(...);
enum {
has_get = sizeof(test_g<T>(0)) == sizeof(yes),
has_element_type = sizeof(test_e<T>(0)) == sizeof(yes)
};
template <typename Q, bool OK = false>
struct get { struct type {}; };
template <typename Q>
struct get<Q, true>
{
typedef decltype(((Q*)nullptr)->get()) type;
};
template <typename Q, bool OK = false>
struct ptr { struct type {}; };
template <typename Q>
struct ptr<Q, true>
{
typedef typename Q::element_type* type;
};
public:
enum {
types_ok = std::is_same<
typename get<T, has_get>::type,
typename ptr<T, has_element_type>::type
>::value,
value = std::is_convertible<T, void*>::value || types_ok
};
};
到目前为止,它似乎工作正常。但是这个推理有问题吗?我应该为不愉快的意外做好准备吗?const
/呢volatile
?
更新(动机):
在评论中你问我的动机,他们是对的,我欠你一个。用例是一个 Lua - C++ 绑定库:当使用 向 Lua 公开一个类实例时,我需要以和的任意组合template <typename T> push_value(T value)
推断底层类型。我需要知道底层类是否已经在活页夹中注册。U
T = U const/volatile/*/&
T = some_pointer<U>
U