2011-07-05 61 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

相關問題