Search code examples
c++templatesc++14template-specializationnon-type-template-parameter

Specialize a method template with type parameter with a non-type one


I'm trying to implement a class template with static member functions that can handle different types. My code looks like this (very simplified example):

#include <array>

struct Foo {
    template<typename T>
    static constexpr size_t foo(T v);
};

template<>
constexpr size_t Foo::foo(double v) {
    return sizeof(v);
}

template<int count>
constexpr size_t Foo::foo(const std::array<int, count>& v) {
    return sizeof(int) * v.size();
}

However, when I try to compile it, I get the following error:

<source>:16:23: error: out-of-line definition of 'foo' does not match any declaration in 'Foo'
   16 | constexpr size_t Foo::foo(const std::array<int, count>& v) {
      |                       ^~~
1 error generated.
Compiler returned: 1

How can I specialise a template with another template?


Solution

  • There is no partial specialzation for function templates, but you can partially specialize a class template:

    #include <array>
    #include <cstddef>
    
    template <typename T> struct Foo_impl;
    
    template <> struct Foo_impl<double> {
        constexpr static size_t value = sizeof(double);
    };
    
    template <size_t count> struct Foo_impl<std::array<int,count>> {
        constexpr static size_t value = count * sizeof(int);
    };
     
    struct Foo {
        template<typename T>
        static constexpr size_t foo(T v) { 
            return Foo_impl<T>::value;
        }
    };
    

    Also note that you must use the right type, size_t not int.