Search code examples
c++templatestemplate-argument-deduction

How to use user-defined deduction guides for multiple template parameters?


Can I use user-defined deduction guides for classes with multiple template parameter? I want that one specified template parameter gets deduced from the constructor argument. All other template parameters must be specified in the <>-bracket when constructing a class. Example:

#include <iostream>

template<typename T, typename A>
struct Hello
{
    Hello(T x) : x(x) {}
    T x;
    A y;
};

Hello<A>(int) -> Hello<int, A>; // This is not a valid syntax but shows what i want to do 

int main()
{    
    Hello h = Hello<float>((int)1); // this should be deduced to Hello<int, float>
    std::cout << h.x << std::endl;
    return 0;
}

Solution

  • I could think about three approaches.

    template <typename T, typename A>
    struct Hello {
      Hello(T x) : x(x) {}
      T x;
      A y;
    };
    
    // Approach 1: use type aliases
    // Requires at least c++-11
    
    template <typename A>
    using HelloInt = Hello<int, A>;
    
    // Approach 2: use function factories
    
    template <typename A>
    Hello<int, A> make_hello_int(int i) {
        return Hello<int, A>(i);
    }
    
    // Approach 3: use template partial deduction
    
    template <typename A, typename T>
    Hello<T, A> make_hello(T i) {
      return Hello<T, A>(i);
    }
    
    int main() {
      // `auto` requires at least c++-11
      auto k = HelloInt<float>(1);
      std::cout << k.x << std::endl;
      std::cout << make_hello_int<float>(2).x << std::endl;
      std::cout << make_hello<float>(3).x << std::endl;
      return 0;
    }