Templates inside templates. Specializing a template class inside a template function

时间:2016-07-11 19:45:12

标签: c++ templates stl

In the following example, I want to get a stl container (either list or unordered_set) using the template function f. I know that the stl container will contain integers.

I tried to use partial template template specialization but it was not working.

How do I achieve what I want?

The code above doesn't compile obviously.

#include <list>
#include <unordered_set>

template <typename T, template C<T>>
C<T> f()
{
    C<T> d;
    d.insert(1);
    return d;
}

int main()
{
    auto l = f<int, std::list<int>>();
    auto s = f<int, std::unordered_set>();

    return 0;
}

Thanks.

3 个答案:

答案 0 :(得分:3)

You're going to have a problem at least in that std::list doesn't take insert the same way std::unordered_set does. The former requires a position; the latter does not.

That aside, I can make it compile and execute with (don't forget you need to instantiate the template):

template <typename T, typename C>
C f()
{
    C d;
    d.insert(1);
    return d;
}

template std::unordered_set<int> f<int, std::unordered_set<int>>();

But you won't be able to use a list this way.

Is this sort of thing acceptable to you? If not, I think you need to clarify your question more as to what you want.

答案 1 :(得分:2)

You can simply create a set of overloaded functions to insert in the container-specific ways you need.

template <typename T>
void f_impl(std::unordered_set<T> & container)
{
    container.insert(1);
}

template <typename T>
void f_impl(std::list<T> & container)
{
    container.push_back(1);
}

template <typename T, template<class...> class C>
C<T> f()
{
    C<T> d;
    f_impl(d);
    return d;
}

then you can do:

auto c1 = f<int, std::unordered_set>();
auto c2 = f<int, std::list>();

to your heart's delight.

答案 2 :(得分:0)

Thanks everyone.

This worked for me. I put it together from the answers you guys posted.

The problem I wanted was much simpler. I wanted to be able to specialize an STL container inside a template function. Obviously, the insert functions are different but I just removed that since I didn't need to insert. I just needed to create the container.

#include <list>
#include <unordered_set>

template <template <class...> class C>
C<int> f()
{
    C<int> d;
    return d;
}

int main()
{
    auto l = f<std::list>();
    auto s = f<std::unordered_set>();

    return 0;
}