2013-10-08 69 views
0

我想基於如果它的模板參數是一個基元類型或容器,使不同的行爲的模板類。基本上,如果模板參數是一個容器,我希望操作push_back在容器上,但如果它是一個原始類型,我希望該類分配給它。請參閱下面的主要部分,瞭解所需行爲的示例具有容器vs原始類型自定義行爲的C++模板化類?

以下是我嘗試做這項工作,但我嘗試了各種各樣的事情後無法編譯它。有人可以告訴我這裏有什麼問題嗎?謝謝!

嘗試1

#include <vector> 

template<typename V> 
struct store_to 
{ 
    static void call(V& d, V const& v) 
    { 
     d = v; 
    } 
}; 

template<typename V, template<typename> class C> 
struct store_to< C<V> > 
{ 
    static void call(C<V>& d, V const& val) 
    { 
     d.push_back(val); 
    } 
}; 

template<typename V> 
struct get_element_type 
{ 
    typedef V value_type; 
}; 

template<typename V, template<typename> class C> 
struct get_element_type< C<V> > 
{ 
    typedef typename C<V>::value_type value_type; 
}; 

template<class T> 
class holder 
{ 
public: 
    typedef T value_type; 
    typedef typename get_element_type<T>::value_type element_type; 

    holder() { } 
    ~holder() { } 

    void store(element_type const& value) 
    { store_to<T>::call(_data, value); } 

    void store_default() 
    { store_to<T>::call(_data, _default_value); } 

    void set_default(element_type const& value) 
    { _default_value = value; } 

    const value_type& data() const 
    { return _data; } 

    const element_type& default_value() const 
    { return _default_value; } 

private: 
    value_type _data; 
    element_type _default_value; 
}; 

int main() 
{ 
    holder<int> x; 
    x.set_default(1); 
    x.store_default(); // e.g. _data = _default_value; 
    x.store(5); // e.g. _data = 5; 

    holder< std::vector<int> > y; 
    y.set_default(5); 
    y.store_default(); // e.g. _data.push_back(_default_value); 
    y.store(0); // e.g. _data.push_back(0); 

    return 0; 
} 

嘗試2

下面是對的std :: list和std :: vector的作品的修改,但它仍然不是很通用的,因爲我想喜歡。有沒有辦法讓任何具有push_back功能和value_type typedef的類C在沒有專門化模板的情況下工作?

#include <vector> 
#include <list> 

template<typename V> 
struct store_to 
{ 
    typedef V outer_type; 
    typedef V inner_type; 

    static void call(outer_type& d, inner_type const& v) 
    { d = v; } 
}; 

template<typename V> 
struct store_to< std::vector<V> > 
{ 
    typedef typename std::vector<V> outer_type; 
    typedef typename outer_type::value_type inner_type; 

    static void call(outer_type& d, inner_type const& val) 
    { d.push_back(val); } 
}; 

template<typename V> 
struct store_to< std::list<V> > 
{ 
    typedef typename std::list<V> outer_type; 
    typedef typename outer_type::value_type inner_type; 

    static void call(outer_type& d, inner_type const& val) 
    { d.push_back(val); } 
}; 

template<class T> 
class holder 
{ 
public: 
    typedef typename store_to<T>::outer_type outer_type; 
    typedef typename store_to<T>::inner_type inner_type; 

    holder() { } 
    ~holder() { } 

    void store(inner_type const& value) 
    { store_to<T>::call(_data, value); } 

    void store_default() 
    { store_to<T>::call(_data, _default_value); } 

    void set_default(inner_type const& value) 
    { _default_value = value; } 

    const outer_type& data() const 
    { return _data; } 

    const inner_type& default_value() const 
    { return _default_value; } 

private: 
    outer_type _data; 
    inner_type _default_value; 
}; 

int main() 
{ 
    holder<int> x; 
    x.set_default(1); 
    x.store_default(); // e.g. _data = _default_value; 
    x.store(5); // e.g. _data = 5; 

    holder< std::vector<int> > y; 
    y.set_default(5); 
    y.store_default(); // e.g. _data.push_back(_default_value); 
    y.store(0); // e.g. _data.push_back(0); 

    return 0; 
} 
+0

還有就是要檢查的東西是一個容器沒有真正的方法,但[這](http://en.cppreference.com/w/cpp/types)的基本類型檢查 – aaronman

+0

概念將提供所需的檢查,如果你可以等到2014年;) – Skeen

回答

0

您可以將插入迭代器傳遞到您的模板而不是整個容器。當您在插入迭代器上調用operator =時,它會向容器添加一個新元素。您需要包含<iterator>標題,並且有幾種可用的類型。

std::vector<int> container; 
MyTemplateFunction(back_inserter(container));