Template Template C++ Function

五迷三道 提交于 2019-12-18 08:46:32

问题


How do I write a template function that operates on a arbitrary container of a arbitrary type? For example how do I generalize this dummy function

template <typename Element>
void print_size(const std::vector<Element> & a)
{
    cout << a.size() << endl;
}

to

template <template<typename> class Container, typename Element>
void print_size(const Container<Element> & a)
{
    cout << a.size() << endl;
}

Here is a typical usage

std::vector<std::string> f;
print_size(f)

This give error

tests/t_distances.cpp:110:12: error: no matching function for call to ‘print(std::vector<std::basic_string<char> >&)’. I'm guessing I must tell the compiler something more specific about what types that are allowed.

What is this variant of template-use called and how do I fix it?


回答1:


Is there a specific reason for you to use a template template? Why not just like this?

template <typename Container>
void print_size(Container const& a)
{
    cout << a.size() << endl;
}

In general, template templates aren’t worth the trouble. In your particular case, there certainly is no use for them, and if you really need to access the member type, I suggest you bow to common practice and use a metafunction (typename Container::value_type in this case).




回答2:


Why ever use something like

template <template<typename> class Container, typename Element>
void print_size(const Container<Element> & a)
{
    cout << a.size() << endl;
}

? Use it in simpler way:

template<typename Container>
void print_size(const Container & a)
{
    cout << a.size() << endl;
}

When calling print_size(f), you will call print_size with Container being vector<string>.




回答3:


The problem is that the vector template takes two type arguments, and your template accepts only template arguments that accept a single argument. The simplest solution is lifting a bit of the type safety and just using Container as a type:

template <typename Container>
void print_size( Container const & c ) {
   std::cout << c.size() << std::endl;
}

Possibly adding static checks (whatever the type Container is, it must have a value_type nested type that is Element...) The alternative would be to make the template template argument match the templates that are to be passed (including allocator for sequences, allocator and order predicate for associative containers)...




回答4:


I know that the question was asked long time ago , but i had same problem , and the solution is that you need to write

template <template <typename,typename> class Container, typename element, typename Allocator>
void print_size(Container<element, Allocator> & a)
{
    std::cout << a.size() << std::endl;
}

because the vector has two template parameters




回答5:


For these types of generic algorithms, I always prefer iterators, i.e.

template <typename IteratorType>
void print_size(IteratorType begin, IteratorType end) {
   std::cout << std::distance(begin, end) << std::endl;
}

To call:

std::vector<std::string> f;
print_size(f.begin(), f.end());


来源:https://stackoverflow.com/questions/7555391/template-template-c-function

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!