std::exchange default template parameter specification

Viewed 68

I would like to understand motivation for why the template parameter U is defaulted to T below, i.e. when is it not deduced from the function argument?

template<class T, class U = T>
  constexpr T exchange(T& obj, U&& new_val)
{
    T old_val = std::move(obj);
    obj = std::forward<U>(new_val);
    return old_val;
}
1 Answers

Paper N3668 motivates the default value for the second template argument with these two examples:

// (1)
DefaultConstructible x = ...;
if (exchange(x, {})) { ... }
// (2)
int (*fp)(int);
int f(int);
double f(double);
/*...*/ exchange(fp, &f) /*...*/

So, basically, it's for convenience. The advantage in the above examples is:

  1. Allow passing a default-constructed DefaultConstructible as new_val without having to spell its type name;
  2. Making a cast of &f to int (*)(int) unnecessary.
Related