Search code examples
c++templatesexplicit-instantiation

Type grouped Explicit Instantiation of templates


If I have a template class with overloaded template member functions(using SFINAE) like:

template <typename T>
struct Foo{
    Foo(T elem);

    template <typename U = T>
    auto get() -> std::enable_if_t<std::is_same_v<U, int>, U>;
    template <typename U = T>
    auto get() -> std::enable_if_t<std::is_same_v<U, bool>, U>;
    T elem_;
};

Now in my CPP file, I must define and explicitly instantiate:

template class Foo<int>;
template int Foo<int>::get<int>();
template class Foo<bool>;
template bool Foo<bool>::get<bool>();
// For all types...T, there will be two statements.

What are different possible ways to do a grouped instantiation by type - something like:

GroupedFooInit<int>(); // does both Foo<int> and Foo<int>::get<int>
GroupedFooInit<bool>(); // similar
.. and so on.

Given that I'm bounded to use C++14, 2 workarounds I could come up with but didnt want/like:
1. Macros: Possible, but would like to strongly avoid.
2. Definition in header, no explicit instantiation needed: Possible, but im working on a huge repo where the file Im dealing with is pretty much included everywhere - so my build times are huge if I go this route for even minor changes.

Link to Code Snippet


Solution

  • You could solve the problem by adding a layer:

    template <typename T>
    struct Foo{
      Foo(T elem);
    
      T elem_;
    
      T get(){
         return do_get<T>();
         }
    
      private:
    
      template <typename U = T>
      auto do_get() -> std::enable_if_t<std::is_same<U, int>::value, U>;
    
      template <typename U = T>
      auto do_get() -> std::enable_if_t<std::is_same<U, bool>::value, U>;
       };
    //If definitions for the do_get functions are provided before these
    //explicit template instantiation definitions, the compiler will certainly
    //inline those definitions.
    template class Foo<int>;
    template class Foo<bool>;