Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 测试类型是否为(智能)指针的通用方法_C++_Templates_Shared Ptr - Fatal编程技术网

C++ 测试类型是否为(智能)指针的通用方法

C++ 测试类型是否为(智能)指针的通用方法,c++,templates,shared-ptr,C++,Templates,Shared Ptr,在我的代码中,我需要测试给定给模板的类型是否是指针——不管它是否智能。根据boost的说法,没有可靠且通用的方法可以做到这一点(请参阅)——或者说有吗 到目前为止,我检查了以下内容: 答:T能否转换为void* B:TT有get()方法吗 C:T是否有一种称为element\u type的类型 D:get()是否返回元素类型* 如果(A | | B&&C&&D),那么我的类型必须是某种指针 以下是模板: template <typename T> class is_pointer

在我的代码中,我需要测试给定给模板的类型是否是指针——不管它是否智能。根据boost的说法,没有可靠且通用的方法可以做到这一点(请参阅)——或者说有吗

到目前为止,我检查了以下内容:

  • 答:
    T
    能否转换为
    void*
  • B:T
    T
    get()方法吗
  • C:
    T
    是否有一种称为
    element\u type
    的类型
  • D:get()是否返回
    元素类型*
如果(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
    };
};
模板
类是指针类型
{
typedef结构{char数组[1];}是;
typedef结构{char数组[2];}否;
模板静态yes测试(decltype(&C::get));
模板静态无测试(…);
模板静态是测试(类型名C::元素类型*);
模板静态无测试(…);
枚举{
has_get=sizeof(test_g(0))==sizeof(yes),
has_element_type=sizeof(test_e(0))==sizeof(yes)
};
模板
结构获取{struct type{};};
模板
结构获取
{
typedef decltype(((Q*)nullptr)->get())类型;
};
模板
结构ptr{struct type{};};
模板
结构ptr
{
typedef typename Q::element_type*type;
};
公众:
枚举{
类型\u ok=std::是否相同<
typename get::type,
typename ptr::type
>::价值,
值=标准::是否可转换::值| |类型|正常
};
};
到目前为止,似乎一切顺利。但这种推理有什么问题吗?我应该为不愉快的惊喜做好准备吗?那么
const
/
volatile

更新(动机):
在你问我的动机的评论中,他们是对的,我欠你一个。用例是一个Lua -C++绑定库:当用“代码>模板推值(t值)< />代码将类实例暴露到Lua时,需要在代码< Ty= u const/Valtual/*/& 和<代码> t=某个指针< /COD>的任何组合中推断出基础类型<代码>代码>代码>。我需要知道底层类
U
是否已经在活页夹中注册。

通过使用boost或定义自定义模板(如

template <typename C> static no test_pointer(C);
template <typename C> static yes test_pointer(C*);
模板静态无测试指针(C);
模板静态是测试_指针(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(...);
template static yes test\u deref(decltype(&C::operator*);
模板静态无测试定义(…);
模板静态是测试箭头(decltype(&C::operator->);
模板静态无测试箭头(…);
并要求两个结果均为“是”。因此,最终的公式可以计算为“普通指针| |(has运算符*&&has运算符->)”


然而,它只是针对智能指针的解决方案。如果您还想将智能指针以外的类型(其他包装器、集合等)传递给Lua,那么情况就完全不同了,我不敢为此提出解决方案。

您正在做boost说无法完成的事情。我已经准备好迎接惊喜了……这不是一个通用的解决方案,它是一个针对特定概念符号的解决方案。如果您遇到一个智能指针,它没有
元素\u类型
,而是有
ptr\u类型
,或者需要使用特征,该怎么办?有些东西可以转换为
void*
,但不是智能指针。特别是:早期对安全bool习惯用法的尝试,包括
std::ios
。您认为为什么需要这个?我认为解决这个“问题”的办法毫无价值。然而,你认为这个问题的解决方案可以像这样解决,但没有告诉我们,是有用的。除非你为图书馆这样做,将模板
声明为类似于
的指针,然后专门针对您实际使用的普通指针和智能指针类型,怎么样?
std::unique\u ptr
是一种成熟的智能指针,它不提供
操作符->
,而是提供
操作符[]
。我明白您的观点,您的观点是正确的。然而,这正是unique_ptr应该被视为智能数组而不是智能指针的原因,尽管unique_ptr的名称不同。如果将这些指针传递给Lua,则必须直接为这些异常添加另一个测试,这是一个缺点。我们能想到类似的例外情况吗?同意。另外,C++11不再需要使用
element\u type
,因为它应该与
decltype(&C::operator*))相同。
如果其他人试图使用visual studio 2013执行此操作,它有时无法正常工作。我在2015年进行了测试,它确实在那里工作,所以我认为这只是一个编译器错误。我可以通过使用
decltype(std::declval().operator*())*
decltype(std::declval().operator->())
来解决这个问题,而不是使用
decltype(&C::operator*)
decltype(&C::operator->)