2017-03-22 14 views
-1

我有類如下。我封裝了矢量來擺脫循環。工作實例可以在link被發現(感謝在評論部分,以幫助)爲原始指針,智能指針和值編譯時間變化的成員函數

template<class T, class U> 
    std::shared_ptr<T> Cast(const std::shared_ptr<U>& spObject) // rename from CastTerrainObject 
    { 
     return std::dynamic_pointer_cast<T>(spObject); 
    } 

    template<class T, class U> 
    T Cast(U* r) 
    { 
     return dynamic_cast<T>(r); 
    } 

    template<typename value> 
    struct A 
    { 

     template < typename T, typename F > 
     T Find(F filterFunction) 
     { 
      return DoFind<T>(filterFunction, std::is_pointer<T>()); 
     } 

     template < typename T, typename F > 
     T DoFind(F filterFunction, std::true_type) 
     { 
      for (size_t i = 0; i < iteratableList.size(); i++) 
      { 
       auto castedTerrain = Cast<T>(iteratableList[i]); 
       if (castedTerrain && filterFunction(castedTerrain)) 
        return iteratableList[i]; 
      } 
      return T(); 
     } 


     template < typename T, typename F > 
     T DoFind(F filterFunction, std::false_type) 
     { 
      for (size_t i = 0; i < iteratableList.size(); i++) 
      { 
       auto castedTerrain = Cast<typename T::element_type>(iteratableList[i]); 
       if (castedTerrain && filterFunction(castedTerrain)) 
        return iteratableList[i]; 
      } 
      return T(); 
     } 

     std::vector<value> iteratableList; 
    } 

我班正在良好的智能指針

std::vector<std::shared_ptr<std::string>> names = { make_shared("needle"), make_shared("manyOtherNames") } ; 
A<std::shared_ptr<std::string>> iterateable{ names }; 
iterateable.Find<std::shared_ptr<std::string>>([] (std::shared_ptr<std::string>){ return *in == "needle";}); 

和原始指針

std::vector<std::string*> names = { new std::string("needle"), new std::string("manyOtherNames") } ; 
A<std::string*> iterateable{ names }; 
iterateable.Find<std::string*>([] (std::string* in){ return *in == "needle";}); 

但現在我想要使​​用它的值以及像(std :: string只是一個例子,我希望我的類可以使用任何非指針和非智能指針類型):

std::vector<std::string> names = { "needle", "manyOtherNames" } ; 
A<std::string> iterateable{ names }; 
iterateable.Find<std::string>([] (std::string in){ return in == "needle";}); 

我還需要一個DoFind,但我無法看到我的案例的類型特徵。 如何組織我的代碼以實現我需要的功能。我限制在Visual Studio 2010中

+2

你可以添加所有的用例(指針,智能指針,價值型)的例子嗎?我真的不明白你想要做什麼 –

+0

希望現在看起來更好。 –

+1

不,你的代碼不起作用:http://melpon.org/wandbox/permlink/WRKPcDp5nwcRyc0k –

回答

1

有幾個問題與您的代碼:

  1. 您的lambda表達式沒有返回一個布爾值:

此:

[] (std::string in){ in == "needle";} 

應該是:

[] (std::string in){ return in == "needle";} 
  1. 你爲什麼試圖在非指針類型上執行dynamic_cast?那些使用static_cast

更改此:

Cast<typename T::element_type>(iteratableList[i]); 

成這樣:

static_cast<T>(iteratableList[i]); 
  • 不過,既然你需要保持你的Cast功能,它足以定義另一個超載來接受一個值,給我們留下三個版本。
  • 請注意,我修改了您的shared_ptr版本,因爲它不正確。

    template<class T, class U> 
    T Cast(const U& r) 
    { 
        return static_cast<T>(r); 
    } 
    
    template<class T, class U> 
    T Cast(const std::shared_ptr<U>& spObject) 
    { 
        return std::dynamic_pointer_cast<typename T::element_type>(spObject); 
    } 
    
    template<class T, class U> 
    T Cast(U* r) 
    { 
        return dynamic_cast<T>(r); 
    } 
    

    Live Demo

    +0

    謝謝我更正。但這不是我所要求的。我試圖避免動態強制類型轉換爲「編譯時」,這就是我所要求的。 –

    +0

    @KadirErdemDemir:我不完全明白。您不必動態投射任何東西。你能否展示一個「理想」的代碼來「避免在編譯時對值類型進行動態轉換」? – AndyG

    +0

    我試圖讓指針,shared_pointer和values.class的類工作,但如果我嘗試使我的類與值的工作,因爲這種動態鑄造編譯失敗。我試圖避免動態鑄造線只在編譯器時間的非指針類型 –