【发布时间】:2014-01-17 00:31:05
【问题描述】:
在 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) 上崩溃和烧毁。
【问题讨论】:
-
我不会对 VC++ 进行模板元编程的能力抱太大希望。至于clang,当
foo是void时,它认为&*foo是可以的,即使没有任何模板。 -
@n.m.: 呃,
&*foo有什么关系呢?我这里没有任何地址... -
我说的是 clang 对取消引用 void* 的看法,而不是代码中的任何内容。
-
@n.m.:但我的意思是当
foo是void*时,clang 肯定不认为sizeof(*foo)没问题,对吧?我不确定我是否看到这两个问题之间的任何关系... -
@n.m.:你怎么能把
foo声明为void开头呢?我以为你的意思是void*。
标签: c++ dereference