0

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.

aep
  • 1,583
  • 10
  • 18
  • The standard library already have [helper classes](https://en.cppreference.com/w/cpp/types/integral_constant) like yours. – Some programmer dude Jul 10 '20 at 15:20
  • And please include the build errors in the question itself, making it self-contained. If that compiler explorer link goes away it will make your question impossible to answer. Remember that Stack Overflow isn't just for you right here and now, but also for people in the future with a similar (or even the exact same) problem. – Some programmer dude Jul 10 '20 at 15:22
  • Template Constructor Template Parameters have to be deduced, there is no way to specify them explicitly. – Taekahn Jul 10 '20 at 15:23
  • @Someprogrammerdude I've pasted the error. I know the stl utilities for the `helper` class in my example, but I am trying to understand what's going on here i.e. the focus is different as the topic says. – aep Jul 10 '20 at 15:27
  • for some reason copying error messages from godbolt has every second line blank, better remove them, and I you find out how to avoid it, tell me! – 463035818_is_not_an_ai Jul 10 '20 at 15:27
  • the focus being on something different is one more reason to use `std::true/false_type`, your helper isnt related to the error, but nevermind... – 463035818_is_not_an_ai Jul 10 '20 at 15:29
  • the dupe is rather old and I am not sure if something changed in newer standards, if thats the case the dupe should get an update – 463035818_is_not_an_ai Jul 10 '20 at 15:31
  • @idclev463035818 How can this be related to a non-type template parameter as in the example ? I don't think it's a dupe. – aep Jul 10 '20 at 15:41
  • @aep it doesnt matter if it is a type or non-type parameter, it isnt possible – 463035818_is_not_an_ai Jul 10 '20 at 15:43
  • if I didnt miss something, the answer in the dupe is in no way specific to type parameters – 463035818_is_not_an_ai Jul 10 '20 at 15:45
  • for the workaround you can use a `std::integral_constant` – 463035818_is_not_an_ai Jul 10 '20 at 15:49
  • that is indeed slightly different. If you cant get the workaround working, I'd be fine with reopening – 463035818_is_not_an_ai Jul 10 '20 at 15:51
  • well acutally you already have the `helper` that you could use as dummy parameter for the constructor – 463035818_is_not_an_ai Jul 10 '20 at 15:52
  • @idclev463035818 Yes, I think if having a fake constructor parameter is the only way to solve this, I think your suggestion works fine and this can be considered a dupe as well. Thanks. – aep Jul 11 '20 at 00:39

0 Answers0