微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何确定C 03中的类型是否可解除引用?

在C 03中,如何确定类型T是否可解除引用?
我的意思是,我如何静态地确定* t是否是T类型t的有效表达式?

我的尝试:

template<bool B,class T = void> struct enable_if { };
template<class T> struct enable_if<true,T> { typedef T type; };

unsigned char (&helper(void const *))[2];
template<class T>
typename enable_if<
    !!sizeof(**static_cast<T *>(NULL)),unsigned char
>::type helper(T *);

template<class T>
struct is_dereferenceable
{ static bool const value = sizeof(helper(static_cast<T *>(NULL))) == 1; };

struct Test
{
    int *operator *();
    void operator *() const;
private:
    Test(Test const &);
};

int main()
{
    std::cout << is_dereferenceable<int *>::value;       // should be true
    std::cout << is_dereferenceable<void *>::value;      // should be false
    std::cout << is_dereferenceable<Test>::value;        // should be true
    std::cout << is_dereferenceable<Test const>::value;  // should be false
}

它适用于GCC(打印1010),但在VC(1110)和Clang(1111)上崩溃和灼伤.

解决方法

#include <boost\type_traits\remove_cv.hpp>
#include <boost\type_traits\is_same.hpp>
#include <boost\type_traits\remove_pointer.hpp>
#include <boost\type_traits\is_arithmetic.hpp>
#include <boost\utility\enable_if.hpp>

namespace detail
{
    struct tag 
    { 
        template < typename _T > 
        tag(const _T &); 
    };

    // This operator will be used if there is no 'real' operator
    tag operator*(const tag &);

    // This is need in case of operator * return type is void
    tag operator,(tag,int);  

    unsigned char (&helper(tag))[2];

    template < typename _T >
    unsigned char helper(const _T &);

    template < typename _T,typename _Enable = void >
    struct traits
    {
        static const bool value = (sizeof(helper(((**static_cast <_T*>(NULL)),0))) == 1);
    };

    // specialization for void pointers
    template < typename _T >
    struct traits < _T,typename boost::enable_if < typename boost::is_same < typename boost::remove_cv < typename boost::remove_pointer < _T > ::type > ::type,void > > ::type >
    {
        static const bool value = false;
    };

    // specialization for arithmetic types
    template < typename _T >
    struct traits < _T,typename boost::enable_if < typename boost::is_arithmetic < typename boost::remove_cv < _T > ::type > > ::type >
    {
        static const bool value = false;
    };
}

template < typename _T > 
struct is_dereferenceable :
    public detail::traits < _T >
{ };

我在msvs 2008中测试过它

原文地址:https://www.jb51.cc/c/118855.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐