Let's say I have a reader class over a file:
class Reader {
public:
template <class T>
T Read();
};
Its only function is the Read
function that reads any arithmetic type (static_assert(std::is_arithmetic_v<T>)
) from a file. Now I want to create a specialization of that function, which reads a vector from the file. How would I go about doing that with templates? Something like the following doesn't work:
template <class T>
std::vector<T> Read<std::vector<T>>();
error: function template partial specialization is not allowed
std::vector<U> Read<std::vector<U>>();
^ ~~~~~~~~~~~~~~~~
You can't partially specialize functions. You can overload them though, but the way of doing it is not obvious, since your function doesn't take any parameters.
First, you need a way to check if a type is a std::vector<??>
:
template <typename T> struct IsVector : std::false_type {};
template <typename ...P> struct IsVector<std::vector<P...>> : std::true_type {};
Then you can plug it into requires
:
template <typename T>
T Read()
{
// Generic overload
}
template <typename T> requires IsVector<T>::value
T Read()
{
// Vector overload
}
Alternatively, you could have a single function, with if constexpr (IsVector<T>::value)
inside.