vendredi 10 juillet 2020

Calling template constructor in a non-template class from derived class [duplicate]

I have a non template base class having a template constructor. In the derived class I'm trying to call the base class constructor in the member initialisation list, but it fails in a compiler error.

#include <iostream>

template <bool>
struct helper;

template <>
struct helper<true> {
  const static bool value{true};
};

template <>
struct helper<false> {
  const static bool value{false};
};

struct timer_base {

  template <bool Bool>
  timer_base(int x) {
    std::cout << "base c'tor with value" << helper<Bool>::value << std::endl;
  }
};

struct timer : timer_base {
  timer(int x) : timer_base<false>(3) {}
};

int main() {
  timer t(4);
  return 0;

godbolt link: https://godbolt.org/z/xa1Yjs

The following error is given by gcc

source>: In constructor 'timer::timer(int)':
<source>:25:18: error: 'struct timer_base timer_base::timer_base' is not a non-static data member of 'timer'
   25 |   timer(int x) : timer_base<false>(3) {}
      |                  ^~~~~~~~~~
<source>:25:28: error: expected '(' before '<' token
   25 |   timer(int x) : timer_base<false>(3) {}
      |                            ^
      |                            (
<source>:25:28: error: no matching function for call to 'timer_base::timer_base()'
<source>:19:3: note: candidate: 'template<bool Bool> timer_base::timer_base(int)'
   19 |   timer_base(int x) {
      |   ^~~~~~~~~~
<source>:19:3: note:   template argument deduction/substitution failed:
<source>:25:28: note:   candidate expects 1 argument, 0 provided
   25 |   timer(int x) : timer_base<false>(3) {}
      |                            ^
<source>:16:8: note: candidate: 'constexpr timer_base::timer_base(const timer_base&)'
   16 | struct timer_base {
      |        ^~~~~~~~~~
<source>:16:8: note:   candidate expects 1 argument, 0 provided

<source>:16:8: note: candidate: 'constexpr timer_base::timer_base(timer_base&&)'
<source>:16:8: note:   candidate expects 1 argument, 0 provided
<source>:25:28: error: expected '{' before '<' token
   25 |   timer(int x) : timer_base<false>(3) {}

My understanding is that, the call to timer_base<false>(3) may be looking for a template class with a non-type template parameter, rather than looking for a template constructor in a non-template class. Is this assumption correct ?

Could someone elaborate the issue and provide a fix for this.

Thanks.

Aucun commentaire:

Enregistrer un commentaire