2011-07-05 63 views
3

我试图实现一个元程序,它发现给定的指针类型是否为const。即为什么SFINAE导致编译器错误,它应该工作?

  • is_const<TYPE*>::valuefalse
  • is_const<const TYPE*>::value应该是true

以下是代码:

template<class TYPE> 
struct is_const 
{ 
    typedef char yes[3]; 
    template<typename T> 
    struct Perform 
    { 
    static yes& check (const T*&); 
    static char check (T*&); 
    }; 

    TYPE it; 
    enum { value = (sizeof(Perform<TYPE>::check(it)) == sizeof(yes)) }; 
}; 

并且编译器错误消息:

In instantiation of ‘is_const<int*>’: 
instantiated from here 
error: no matching function for call to ‘is_const<int*>::Perform<int*>::check(int*&)’ 
note: candidates are: static char (& is_const<TYPE>::Perform<T>::check(const T*&))[3] [with T = int*, TYPE = int*] 
note: static char is_const<TYPE>::Perform<T>::check(T*&) [with T = int*, TYPE = int*] 

我的焦点已转移到错误消息。如果你看到最后一行:

note: static char is_const<TYPE>::Perform<T>::check(T*&) [with T = int*, TYPE = int*] 

如果我们真正取代T = int*TYPE = int*那就真的应符合相应的功能(char check())。我急于想知道这里出了什么问题。

+1

这是什么编译器? –

+2

如果'T'是'int *',那么'T *&'是'int **&'。所以我不认为签名匹配... – Nemo

+0

@iammilind:不,它不应该匹配,你有'void foo(int **&)'和'int * p; foo(p);','p'是一个指向int的指针,而不是指向int的指针。 –

回答

9

为什么这么迂回?怎么样直接的特质类:

#include <functional> 

template <typename T> struct is_const_ptr : std::false_type { }; 
template <typename T> struct is_const_ptr<const T *> : std::true_type { }; 

struct Foo {}; 

int main() 
{ 
    std::cout << is_const_ptr<Foo*>::value << is_const_ptr<const Foo*>::value << std::endl; 
} 
+0

+1,即使在问题中他不清楚他想检查的是什么,在指针的情况下外部类型还是指向类型是常量...我会从专业化中移除'*'... –

+0

@Dribeas:只是'is_const'?但我们正在测试“指向const T的指针”,而不是“const指向T的指针”...... –

+0

这就是为什么我选择了upvoted,因为这个答案很清楚:'is_const_ptr'非常明确。 –

1

这是你的问题:

static yes& check (const T*&); 
static char check (T*&); 

当你实例is_const<int*>,你的函数定义扩展为:

static yes& check (const int**&); 
static char check (int**&); 

然而,临时项目(TYPE it)类型为int*,就像您指定的那样。你需要改变你的check函数签名删除指针符,就像这样:

static yes& check (const T&); 
static char check (T&); 
+0

类型的权利......在'const'检查的情况下,签名可能是'static yes&check(int * const *&)'而不是'static yes&check(int const **&)'已经说过。 –

+0

我试过这种修改,但它似乎并没有工作。在http://www.ideone.com/fMlxb查看输出结果 – iammilind

1

有两件事情错在你的代码。

首先,下面

static yes& check (const T*&); 
static char check (T*&); 

必须改变,以

static yes& check (const T&); 
static char check (T&); 

答二,it成员必须是static

static TYPE it; 

,或者只是通过((TYPE)0)到您的支票功能。无需该成员。

+0

+1'(sizeof(执行 :: check((TYPE)0))''将在编译时计算 –

+1

它会在编译时评估if它也是'检查(it)',@VJo –

+0

我试过这个修改,但它似乎仍然不起作用。请参阅http://www.ideone.com/fMlxb上的输出 – iammilind

相关问题