如何确定类型在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 <boosttype_traitsremove_cv.hpp>
#include <boosttype_traitsis_same.hpp>
#include <boosttype_traitsremove_pointer.hpp>
#include <boosttype_traitsis_arithmetic.hpp>
#include <boostutilityenable_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中测试过它
这是叮当声中的一个错误。 有人应该提交报告。
Clang实现了在void指针上做指针运算的旧gcc扩展。 这包括能够解引用void指针,并取sizeof(void)
。 铿锵这样做是因为人们过去常抱怨可以用gcc编译的旧代码而不是叮当声。 所以铛维护者继续并且实施这个扩展。 这里的问题有很多种:
sizeof(void)
在模板中使用时会产生替换失败,尽管只是一个警告。 与铿锵++,它不。 -Wpointer-arith -Werror
禁用clang ++中的扩展,但这会导致sizeof(void)
是编译错误而不是替换失败。 我不能担保VC ++。
链接地址: http://www.djcxy.com/p/76437.html上一篇: How to determine if a type is dereferenceable in C++03?