2013-04-20 68 views
0

我一直在爲這個問題奮鬥了大約半天,至少XCode 4.6有一個bug模板類的某些聲明會違反語言並允許將類內的常量數據傳遞給外部函數,其參數delcared as const修飾符。XCODE 4.6使用函數指針作爲模板類中的參數的C++模板函數

下面的例子將編譯, Tcaller ::()方法調用的甚至強硬模板聲明規定作爲參考 但靜態CMP功能是提供無用* const的&改良劑通過常量參數。

template< typename T> struct Tcalled 
{ 
    // !!!error - this prototype doesn't protect the data passed to function 
    // because it should be declared with const modifiers but it wouldn't compile then. 
    // SEE: Below my NOTE for correct function prototype. 
     static bool cmp(const Tcalled*& item, const int& key) //<- correct but doesn't work 
     static bool cmp(Tcalled* const & item, const int& key) //<- invalid but works!! 
     { 
      return (item->index = key); /// error - we modify const object here ! 
     } 

    T index; 
}; 

template < typename T> struct Tcaller 
{ 
    Tcaller(){} 

    template < typename K, bool (*compare)(const T& item, const K& key) > 
    bool call(int k) const { return compare(data, k); } 

    T  data; 

}; 


int main(int argc, char *argv[]) 
{ 
    const Tcaller<Tcalled<int>* > tmp; // <- const data 
    int k = 1; 

    tmp.call<int,Tcalled<int>::cmp>(k); //call here WILL modify const data !! 

} 

而且這樣的問題:我怎麼能強迫的XCode服從規則,允許我爲原型 我的靜態函數,因爲它是申報模板參數?至於現在這些都在Xcode的錯誤,我是說我正確宣告我的靜態方法:

呼叫到「呼叫」 候選模板不匹配的成員函數忽略:模板參數「比較」

無效顯式指定的參數

謝謝!

+0

'常量Tcalled *'是指針爲const Tcalled,'Tcalled * const'是常量指針Tcalled。他們是不同的東西 – yngccc 2013-04-20 22:04:08

回答

2

大概你的意思是說,它的工作原理是當參數聲明爲Tcalled<T>* const & itemcmp的主體應該使用==而不是=

您對模板參數實例化的方式存在誤解。這不僅僅是模板參數的複製粘貼替換。你預計const T&T實例化爲Tcalled<int>*將相當於const Tcalled<int>*&;也就是說,一個「參考指針爲const Tcalled<int>

然而,這是錯誤的,const適用於整個T類型。因此,其實,實例化後,const T&相當於Tcalled<int>* const&。這就是爲什麼有爭論聲明如Tcalled* const & item工作正常

爲了得到這與聲明爲const Tcalled<T>*& item工作,許多事情必須改變:

  1. call函數模板argume NTS應定義像這樣:

    template < int (*compare)(T& item) > 
    

    即,函數指針類型需要T&,而不是一個const T&。這是有意義的,因爲cmp函數根本不參考const對象(它引用非const指針)。

  2. call功能不應const

    int call() { return compare(data); } 
    

    這是因爲它通過其構件T比較,這是一個參考到非const對象(指針本身不是const)。它不能這樣做,如果它是const函數,因爲它不能保證compare不會修改該對象。

  3. Tcaller必須T作爲const Tcalled<int>*被實例:

    Tcaller<const Tcalled<int>* > tmp; 
    
+0

感謝您花時間回答。我想到了這一點,但仍然如此,編譯器允許實際修改const對象 - 請參閱上面我更新的代碼。我不應該依賴編譯器的消息或警告嗎? Plus - 仍然是一個有效的問題 - 如何在外部靜態函數中使用正確的方法來保存'constness'? – seeoneself 2013-04-20 22:02:05

+0

@seeoneself看到我的編輯修復。 – 2013-04-20 22:04:59

+0

我很害怕這個解決方案是誠實的!我最初做了,但是這迫使我在模板中只有const數據 - 因爲這只是一個虛擬的例子,它可能看起來像一個很好的解決方案,但在實際的代碼中,我會堅持const數據類型作爲模板參數,這是不可接受的這是非const數據的容器類.. confused:S – seeoneself 2013-04-20 22:10:12