Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Specialize template of templated data type

I have this situation:

#include <vector>

template<typename T>
T f() { return T(); }

template<>
template<typename T>
std::vector<T> f<std::vector<T>>() {
    return { T() };
}

int main(){
    f<std::vector<int>>();
}

I'm trying to specialize the template for std::vector<T>, but I'm getting this error:

error: too many template-parameter-lists

std::vector<T> f<std::vector<T>>() {

How can I specialize for std::vector<T>?

like image 528
João Paulo Avatar asked May 20 '19 13:05

João Paulo


People also ask

What is a specialized template?

The act of creating a new definition of a function, class, or member of a class from a template declaration and one or more template arguments is called template instantiation. The definition created from a template instantiation is called a specialization.

What is template What are the types of templates?

There are three kinds of templates: function templates, class templates and, since C++14, variable templates. Since C++11, templates may be either variadic or non-variadic; in earlier versions of C++ they are always non-variadic.

Which of the data types are supported by template?

All data types, both primitive and compound types, must be defined by using a template.


2 Answers

There's no such thing as partially specialized function templates. What you are doing is creating a new template, so the correct syntax would be:

template<typename T>
std::vector<T> f() {
    return { T() };
}

This overloads the function name f and the two templates are independent. But by having both overloads will make almost all calls to f ambiguous including the one example in your main().

EDIT:

Had you removed the template<> line which would be invalid for class partial specializations too then clang generates more helpful error message:

error: non-class, non-variable partial specialization f<std::vector<T,std::allocator<_Tp1> > > is not allowed

std::vector<T> f<std::vector<T>>() {
like image 100
Quimby Avatar answered Oct 27 '22 00:10

Quimby


If a problem is X, and a solution is Y, then usually specialization of function templates is Z. That's when specialization is possible anyway. You can't partially specialize function templates, only overload them.

A solution here would be to use a helper. A class template, which you can specialize, that will do the work. Meanwhile the function template only forwards to it.

namespace detail {
    template<typename T>
    struct f {
        static T work() { return T(); }
    };

    template<typename T>
    struct f<std::vector<T>> {
        static std::vector<T> work() { return {T()}; }
    };
}

template<typename T>
T f() { return detail::f<T>::work(); }
like image 21
StoryTeller - Unslander Monica Avatar answered Oct 27 '22 00:10

StoryTeller - Unslander Monica