mar*_*n78 9 c++ templates shared-ptr
在我的代码中,我需要测试给模板的类型是否是指针 - 无论是否聪明.根据提升,没有可靠和通用的方法(见这里) - 或者有吗?
到目前为止,我检查以下内容:
T转换为void*?T有get()方法吗?T没有叫做element_type?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
};
};
Run Code Online (Sandbox Code Playgroud)
到目前为止,似乎没问题.但这种推理有什么问题吗?我应该为不愉快的惊喜做好准备吗?怎么样const/ volatile?
在评论中你要求我的动机,他们是对的,我欠你一个.用例是一个Lua - C++结合库:暴露一个类的实例时到Lua用template <typename T> push_value(T value),我需要推断的基础类型U中的任何组合T = U const/volatile/*/&和T = some_pointer<U>.我需要知道底层类U是否已经使用绑定器进行了注册.
检查类型是否是指针很容易,可以使用 boost 或定义具有专门化的自定义模板,例如
template <typename C> static no test_pointer(C);
template <typename C> static yes test_pointer(C*);
Run Code Online (Sandbox Code Playgroud)
但如果您更喜欢的话,可以坚持使用 void* 解决方案。
要检查智能指针,我建议检查适当的运算符。我认为只有当一个类型同时定义了operator*和operator->时才可以被认为是智能指针。所以你应该检查
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(...);
Run Code Online (Sandbox Code Playgroud)
并要求两个结果均为“是”。所以,最终的公式可以计算为“普通指针||(has operator* && hasoperator->)”。
然而,它只是针对智能指针的解决方案。如果你还想将智能指针以外的类型(其他包装器、集合等)传递给 Lua,那么这是一个完全不同的故事,我不敢为此提出解决方案。