2014-05-06 242 views
1
#include <iostream> 
#include <boost/shared_ptr.hpp> 
#include <boost/make_shared.hpp> 
using namespace std; 

struct TestClass 
{  
    static void Create(boost::shared_ptr<const int> shp) 
    { 
     cout << "TestClass::Create: " << *shp << endl; 
    } 


    template <typename T> 
    static void CreateT(boost::shared_ptr<const T> shp) 
    { 
     cout << "TestClass::CreateT: " << *shp << endl; 
    } 


}; 

int main() 
{ 
    boost::shared_ptr<int> shpInt = boost::make_shared<int>(10); 
    boost::shared_ptr<const int> shpConstInt = shpInt; 

    TestClass::Create(shpInt);  // OK 
    TestClass::Create(shpConstInt); // OK 

    //error C2664: 'void TestClass::CreateT<int>(boost::shared_ptr<T>)' : 
    //cannot convert parameter 1 from 'boost::shared_ptr<T>' to 'boost::shared_ptr<T>' 
    TestClass::CreateT(shpInt);  // ERROR 

    TestClass::CreateT(shpConstInt); // OK 

    // workaround 
    boost::shared_ptr<const int> shpConstInt2 = shpInt; 
    TestClass::CreateT(shpConstInt2);  // OK 

    return 0; 
} 

問題>爲什麼TestClass::CreateT(shpInt)不起作用,而TestClass::Create(shpInt)正常工作。是否因爲TestClass::CreateT是僅支持靜態綁定的模板函數,無法自動從boost::shared_ptr<T>轉換爲boost::shared_ptr<const T>靜態非模板成員函數與靜態模板成員函數

謝謝

+0

對於'CreateT',它應該嘗試轉換哪一個(許多'T'可能是可能的)?順便說一句,'CreateT (shpInt)'應該有效。 – Jarod42

+0

是的,它在我做出更改後生效。爲什麼最初的那個不起作用? – q0987

+0

我的意思是:如何boost :: shared_ptr '和'boost :: shared_ptr '有關係嗎? (你期望'T == U') – Jarod42

回答

2

非模板版本的工作,因爲沒有涉及類型推演。編譯器知道和類型的類型爲他必須轉換(如果它們不是相同的類型),並簡單地檢查是否有可能的轉換。

對於模板版本,這不再是真實的。他首先必須推導出模板。

boost::shared_ptr<const int>boost::shared_ptr<const T>,因爲一個完美的匹配,發現這個很簡單:Tint(所以需要也不參與任何轉換)。

對於從boost::shared_ptr<int>boost::shared_ptr<const T>的匹配,沒有產生相同兩種類型的T。所以問題是'什麼是T?' 對你來說它可能是顯而易見的(你仍然是錯的),但編譯器不能推導出T,因爲它不是一個完美的匹配。次好的是兩種類型之間的轉換,但這意味着要嘗試T(它們是無限的)的所有可能性,並查看哪一種產生可轉換類型。例如。 T = long - >boost::shared_ptr<const long>可以是轉換爲boost::shared_ptr<int>T = Foo(其中Foo是一個用戶定義的類) - >boost::shared_ptr<const Foo>可以是轉換爲boost::shared_ptr<int>。所以他無法推斷出T。我知道這不是一個學術答案,而對標準更爲了解的人可以從標準中引用類型推導規則,但最終這些規則有些受到上述解釋的啓發。