Search code examples
c++language-lawyerc++17variadic-templatestemplate-argument-deduction

Difference between references and values in deduction guides


Considering type A:

template <typename T, size_t N>
struct A
{
    T arr[N];
};

Is there any difference between C++17 user-defined deduction guides

template <typename T, typename ... Ts>
A(const T&, const Ts& ...) -> A<T, 1 + sizeof...(Ts)>;

and

template <typename T, typename ... Ts>
A(T, Ts ...) -> A<T, 1 + sizeof...(Ts)>;

?

Or, in other words is there any difference between const references and values in deduction guides?


Please note that the question is not about template function type deduction, but about the new C++17 feature, user-defined deduction guides for class template argument deduction, so you can simply declare A instance{1,2,3} instead of A<int, 3> instance{1,2,3}.


Solution

  • Or, in other words is there any difference between const references and values in deduction guides?

    In your case maybe not but, generally speaking, yes.

    When T isn't copyable.

    In the following example the first case (const reference) compile receiving a std::unique_ptr<int>, the second one (value) gives an error

    #include <iostream>
    #include <memory>
    
    template <typename T, size_t N>
    struct A
     { template <typename ... Ts> A (Ts const & ...) {} };
    
    template <typename T, size_t N>
    struct B
     { template <typename ... Ts> B (Ts const & ...) {} };
    
    template <typename T, typename ... Ts>
    A(T const &, Ts const & ...) -> A<T, 1U + sizeof...(Ts)>;
    
    template <typename T, typename ... Ts>
    B(T, Ts ...) -> B<T, 1 + sizeof...(Ts)>;
    
    
    int main()
     {
       std::unique_ptr<int> up;
    
       auto a = A{up};    // compile
       // auto b = B{up}; // doesn't compile
     }