2013-10-08 43 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));