2012-08-02 87 views
3

爲什麼我必須將int *更改爲typedef int * IntPtr才能編譯?const int *&vs typedef int * IntPtr

template <class T> 
class A 
{ 
    public: 
     template <class X> 
     void a(X *x, void (X::*fun)(const T&)) 
     { 
     } 
}; 

typedef int * IntPtr; 

class B 
{ 
    public: 
     B() : a() 
     { 
      a.a(this, &B::foo); // this won't work 
     } 
     void foo(const int *&) // must replace `int *` here with `IntPtr` 
     { 
     } 
     A<int *> a; // ...and here 
}; 

class C 
{ 
    public: 
     C() : a() 
     { 
      a.a(this, &C::foo); 
     } 
     void foo(const IntPtr&) 
     { 
     } 
     A<IntPtr> a; 
}; 

我明白爲什麼typedefs是有用的,但不是爲什麼他們是必需的。類C編譯好B沒有。

這是MSVC++ 2008編譯器編譯錯誤:

Error 1 error C2784: 'void A<T>::a(X *,void (__thiscall X::*)(const T &))' : could not deduce template argument for 'void (__thiscall X::*)(const T &)' from 'void (__thiscall B::*)(const int *&)' 
+0

你可以發佈的代碼,因爲它不會編譯? – Hbcdev 2012-08-02 13:32:44

+0

我會檢查這段代碼是否會重現問題(它應該)。我目前正在使用MSVC 2008編譯器。 – 2012-08-02 13:33:58

+3

'do'是一個關鍵字! – MvG 2012-08-02 13:37:38

回答

13

const int*&typedef int* IntPtr; const IntPtr&是不一樣的。在第一種情況下,它的int是常量,在第二種情況下它是指針。只有第二種情況與您的模板兼容。

如果你寫

void foo(int * const &); 

相反,它應該編譯和工作得很好。

+5

當然,這是爲什麼你總是應該在'const'之後。如果你寫了'IntPtr const',很明顯這不是'int const *',而是'int * const'。 – 2012-08-02 13:39:00