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>
?
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.
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.
All data types, both primitive and compound types, must be defined by using a template.
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 allowedstd::vector<T> f<std::vector<T>>() {
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(); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With