测试类型是否为(智能)指针的通用方法
在我的代码中,我需要测试赋予模板的类型是否为指针--无论它是否智能。根据Boost的说法,没有可靠和通用的方法来做到这一点(参见here)--或者有吗?
到目前为止,我检查了以下内容:
- A:
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++绑定库:当使用template <typename T> push_value(T value)
向Lua公开一个类实例时,我需要推导出T = U const/volatile/*/&
和T = some_pointer<U>
任意组合的底层类型U
。我需要知道基础类U
是否已注册到绑定器。
解决方案
很容易检查类型是否为指针,无论是使用Boost还是使用以下专门化定义自定义模板
template <typename C> static no test_pointer(C);
template <typename C> static yes test_pointer(C*);
但如果您更喜欢,可以继续使用VOID*解决方案。
要检查智能指针,我建议改为检查适当的运算符。我认为只有在同时定义了运算符*和运算符->的情况下,类型才能被视为智能指针。因此,您应该检查
template <typename C> static yes test_deref(decltype(&C::operator*));
template <typename C> static no test_deref(...);
template <typename C> static yes test_arrow(decltype(&C::operator->));
template <typename C> static no test_arrow(...);
并要求两个结果都为"YES"。因此,最终的公式可以计算为"正常指针||(Has OPERATOR*&;&;Has OPERATOR->)"。
然而,它只是一种智能指针的解决方案。如果您还想将智能指针(其他包装、集合等)以外的类型传递给Lua,那就完全是另一回事了,我不敢提出解决方案。
相关文章