1

Consider the following example.

static constexpr std::array<bool, 2> Default{true, false};

template <size_t n>
void process(const std::array<bool, n>& values = Default) {
  // do some work...
}

template <size_t n = Default.size()>
void process2(const std::array<bool, n>& values = Default) {
  // do some work...
}

void test() {
  process();         // error: cannot infer n
  process(Default);  // works fine
  process2();        // works fine
}

The call to process() fails because it cannot infer n, even though it should in theory be able to. To get this to work, I have to specify the default in 2 places, as in process2, which seems inelegant and prone to error.

Is this the expected behavior? If so, is it possible that support for this could be added to the language?

Amaar
  • 337
  • 2
  • 13
  • 1
    *" I have to specify the default in 2 places"*. Alternative is to get rid of default argument and use 2 overloads `void process() { return process(Default); }` – Jarod42 Aug 18 '22 at 21:55
  • 1
    *"Is this the expected behavior"*. yes, default argument doesn't participe to deduction. – Jarod42 Aug 18 '22 at 21:56
  • related/dup: [why-cant-the-compiler-deduce-the-template-type-from-default-arguments](https://stackoverflow.com/questions/9628974/why-cant-the-compiler-deduce-the-template-type-from-default-arguments). – Jarod42 Aug 18 '22 at 21:59

1 Answers1

0

Is this the expected behavior?

Yes. Default parameter values do not contribute to template argument deduction.

If so, is it possible that support for this could be added to the language?

Unlikely. It's clear what you want in this simple case, but once template specialization comes into play you can get into situations where this simply does not work. Consider the following:

template <typename T, size_t N>
void foo(const std::array<T, N>& = {true, false}) {}

template <>
void foo<bool, 2>(const std::array<bool, 2>&) {}

If default parameter values were considered when doing template argument deduction, then foo() would use {true, false} to deduce T = bool, N = 2, but now that means the specialization needs to be selected after the base template has been (partially?) instantiated. Not only that the specialization doesn't have a default parameter value. Should it "inherit" the base template's default? Function template specializations don't currently do that, so this would have to be some sort of special case. And this is just the first thing I thought of.

Perhaps issues like these could be overcome, but they would significantly complicate an already complicated part of the language. Thus far that has not been deemed to be worth it.

Miles Budnek
  • 28,216
  • 2
  • 35
  • 52