C ++模板类,包含容器与原始类型的自定义行为?

时间:2013-10-08 14:35:24

标签: c++ templates containers

我正在尝试根据模板参数是基本类型还是容器来创建具有不同行为的模板化类。基本上,如果模板参数是一个容器,我想在容器上操作push_back,但如果它是一个基本类型,我希望该类分配给它。请参阅下面的主要内容,了解所需行为的示例。

这是我尝试这项工作的尝试,但在尝试各种各样的事情之后我无法进行编译。谁能告诉我这里出了什么问题?谢谢!

尝试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;
}

1 个答案:

答案 0 :(得分:0)

您可以将插入迭代器传递给模板而不是整个容器。在插入迭代器上调用operator =时,它会向容器添加一个新元素。您需要包含<iterator>标题,并且有几种不同的类型。

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