2013-05-08 22 views
3

方法我有一個模板action方法接受任何種類的容器STL的C。然而所包含項目(C::value_type)必須是ClassAClassB。到目前爲止好:C++ 11:專營/限制上取決於容器的VALUE_TYPE

struct Whatever { 
    template<typename C> 
    void action(const C& c) { 
     static_assert(std::is_same<typename C::value_type, ClassA>::value || 
         std::is_same<typename C::value_type, ClassB>::value, 
         "Wrong C::value_type"); 
     // do something with c 
    } 
}; 

// Usage: 
Whatever w; 
w.action(std::vector<ClassA>{1, 2, 3}); 
w.action(std::unordered_set<ClassB>{1, 2, 3}); 

注:封閉類是模板,唯一的模板是這種非常action方法。

現在,根據C::value_type,我想專門化該方法的行爲。你猜對了,那是我的大腦開始融化的地方。


我相信SFINAE是去的方式,但很明顯,我太生疏,使其正常工作:幾個小時後,對我自己的健康噸幫手structs和太多的咖啡,編譯器只是不停地喊我通常500+模板錯誤。在這裏無論是抄襲我的助手structs或錯誤沒有意義的,這幾乎是無用的垃圾。然而,我不得不承認,自從一個好的十年以來,我並沒有真正與所有的C++模板(r)進化(甚至是使用SFINAE)保持聯繫,所以難怪我沒有這麼努力。

我強烈懷疑C++ 11現在擁有簡單,隨時可用的類似SFINAE的工具來實現我想要的功能,但我甚至不知道從文檔中開始搜索的位置。搜索引擎都於事無補,一次爲我能夠明白什麼是有實在太多新的信息/不相關的我的問題。

因爲我在一個總的損失,我就帶寶貝臺階上,要求SO ...我的問題是雙重的:

  • 我如何專注的方法取決於行爲利用現代C++模板11工具C::value_type的實際類型?
  • 可選,有檢查C實際上是一個容器,一個標準的方式?

感謝您的關注。

回答

3

我想知道你爲什麼不這樣做:

template<typename C> 
void action(const C& c) 
{ 
     static_assert(std::is_same<typename C::value_type, ClassA>::value || 
         std::is_same<typename C::value_type, ClassB>::value, 
         "Wrong C::value_type"); 

     action_worker(c, static_cast<typename C::value_type*>(0)); 
} 

private: 

template<typename C> 
void action_worker(const C& c, ClassA *) 
{ 
    //specialized code when C::value_type is ClassA 
} 

template<typename C> 
void action_worker(const C& c, ClassB *) 
{ 
    //specialized code when C::value_type is ClassB 
} 

現在取決於C::value_type,第二個參數action_worker可以是ClassA*ClassB*。這將使編譯器能夠在您編寫專用代碼的地方選擇正確的重載。

對於你的問題的第二部分,看到這個答案的is_container類模板的實現:

希望有所幫助。

+0

噢,我的,傻傻的我......我應該*。*我想過,但我是在這樣的相反方向搜索,我可能永遠不會有。 O_o非常感謝!對於我的問題的第一部分來說,這絕對是一個很好的答案,非常直截了當。 – syam 2013-05-08 04:25:25

+0

@syam:查看編輯。它鏈接到解決問題的第二部分。 – Nawaz 2013-05-08 04:40:33

+0

再次感謝,你釘了它。希望我能再次讓你高興。 ;) – syam 2013-05-08 04:44:08

1

因爲你只支持這兩種類型我會考慮使用enable_if:

struct Whatever 
{ 
    template<typename C> 
    typename std::enable_if<std::is_same<typename C::value_type, ClassA>::value, void>::type 
    action(const C& c) 
    { 
     std::cout << "ClassA\n"; 
    } 

    template<typename C> 
    typename std::enable_if<std::is_same<typename C::value_type, ClassB>::value, void>::type 
    action(const C& c) 
    { 
     std::cout << "ClassB\n"; 
    } 
}; 
+0

的確,那是我原來的那種東西。謝謝,現在我有地方開始調查這些新功能...... :) – syam 2013-05-12 12:48:38