具有功能的所有容器类型的模板begin()end()size()

时间:2016-01-22 12:48:26

标签: c++ templates

为矢量编写以下模板代码。它不会编译,因为一个调用使用的是list而不是vector。我想重写模板,以便它适用于任何容器。对该容器的限制是它需要包含类型T,具有begin(),具有end()并具有size();

可以使用模板完成吗? 我该怎么做?

#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <typeinfo>

namespace std
{
    template <typename T>
    string to_string(T s) { return typeid(T).name(); }
    string to_string(string s) { return s; }
}

template<typename T, typename A = std::allocator<T>>
static std::string range_to_string(std::vector<T, A> const& vec)
{
    bool more = false;
    std::string str = "size:" + std::to_string(vec.size()) + " [";
    for (const T & item : vec)
    {
        if (more) { str += ", "; }
        str += std::to_string(item);
        more = true;
    }
    str += "]";
    return str;
}

void demo1()
{
    std::string dat[] = {"one", "two", "three"};
    std::vector<std::string> vs(dat, dat + 3);
    std::cout << range_to_string(vs) << std::endl;
}

void demo2()
{
    std::list<short> ls= {1, 2, 3, 4};
    std::cout << range_to_string(ls) << std::endl;
}

int main()
{
    demo1();
    demo2();
    return 0;
}

2 个答案:

答案 0 :(得分:3)

我找到了答案here

看起来这是常识。

#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <typeinfo>

namespace std
{
    template <typename T>
    string to_string(T s) { return typeid(T).name(); }
    string to_string(short s) { return to_string((int) s); }
    string to_string(string s) { return s; }
}

template<typename T, typename A = std::allocator<T>, template <typename, typename> class container>
static std::string range_to_string(container<T, A> const& vec)
{
    bool more = false;
    std::string str = "size:" + std::to_string(vec.size()) + " [";
    for (const T & item : vec)
    {
        if (more) { str += ", "; }
        str += std::to_string(item);
        more = true;
    }
    str += "]";
    return str;
}

void demo1()
{
    std::string dat[] = {"one", "two", "three"};
    std::vector<std::string> vs(dat, dat + 3);
    std::cout << range_to_string(vs) << std::endl;
}

void demo2()
{
    std::list<short> ls= {1, 2, 3, 4};
    std::cout << range_to_string(ls) << std::endl;
}

int main()
{
    demo1();
    demo2();
    return 0;
}

答案 1 :(得分:2)

只要您不必使编译器出错就可以使用没有的容器来调用该函数我只会使用

template<typename Container>
static std::string range_to_string(Container const& cont)
{
    bool more = false;
    std::string str = "size:" + std::to_string(cont.size()) + " [";
    for (const auto & item : cont)
    {
        if (more) { str += ", "; }
        str += std::to_string(item);
        more = true;
    }
    str += "]";
    return str;
}

这适用于begin()end()size()的所有类型。这也适用于任何不像地图容器container_name<type, allocator>形式的容器。

如果有人传递了那些没有那些东西的东西,那么你的函数试图使用它的函数就会出现编译器错误。