Search code examples
c++templatestemplate-argument-deductiondefault-arguments

Why can't the compiler deduce template type parameters from default function arguments?


I was surprised the following code resulted in a could not deduce template argument for T error:

struct foo
{
  template <typename T>
  void bar(int a, T b = 0.0f)
  {
  }
};

int main()
{
  foo a;
  a.bar(5);

  return 0;
}

Calling a.bar<float>(5) fixes the issue. Why can't the compiler deduce the type from the default argument?


Solution

  • In C++03, the specification explicitly prohibits the default argument from being used to deduce a template argument (C++03 §14.8.2/17):

    A template type-parameter cannot be deduced from the type of a function default argument.

    In C++11, you can provide a default template argument for the function template:

    template <typename T = float>
    void bar(int a, T b = 0.0f) { }
    

    The default template argument is required, though. If the default template argument is not provided, the default function argument is still not usable for template argument deduction. Specifically, the following applies (C++11 14.8.2.5/5):

    The non-deduced contexts are:

    ...

    • A template parameter used in the parameter type of a function parameter that has a default argument that is being used in the call for which argument deduction is being done.