簡體   English   中英

靜態非模板成員函數與靜態模板成員函數

[英]static non-template member function vs. static template member function

#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>

謝謝

非模板版本有效,因為不涉及類型歸約。 編譯器知道要轉換的類型和要轉換的類型 (以防它們不是同一類型),並簡單地檢查是否存在轉換的可能性。

對於模板版本,這不再是正確的。 他首先必須推斷出模板。

對於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 我知道這不是一個學術上的答案,對標准更了解的人可以引用標准中的類型推導規則,但最終這些規則在某種程度上受上述解釋的推動。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM