Search code examples
c++templatestemplate-specialization

Specialize template function to return vector


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>>();
               ^   ~~~~~~~~~~~~~~~~

Solution

  • 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.