2

the header mycomputationclass.h:

#pragma once
template<typename numberType, bool increaseByOne>
class MyComputationClass
{
   numberType a = 1;
   numberType b = 2;
   numberType compute();
};

#include mycomputationclass.hpp

the header implementation file mycomputationclass.hpp:

#pragma once
#include mycomputationclass.h

template<typename numberType, bool increaseByOne>
numberType MyComputationClass<numberType, increaseByOne>::compute()
{
   return a + b;
}
template<typename numberType>
numberType MyComputationClass<numberType, true>::compute()
{
   return a + b + static_cast<numberType>(1);
}

the error:

 error: invalid use of incomplete type ‘class MyComputationClass<numberType, true>’
 numberType MyComputationClass<numberType, true>::compute()
                                                          ^

All topics related to specialisation I find are using only one template. Can anyone please help me out here?

Jan Hackenberg
  • 481
  • 3
  • 14

1 Answers1

1

First of all please see Why can templates only be implemented in the header file?. Now, your problem doesn't stem from the above, but nevertheless you should strongly consider if you indeed want to implement the template in the cpp file. I suspect you do not.

Anyway the problem you are asking about is that you are trying to define a method of a specialized class template which you haven't specialized.

There are a couple of options here.

  • You can specialize the class template, repeating the whole body

    template<typename numberType>
    class MyComputationClass<numberType, true>
    {
       numberType a = 1;
       numberType b = 2;
       numberType compute();
    };
    
  • You can create a base class template with all the common code and have derived classes templates with only the parts you need to specialize

  • In C++17 you can use if constexpr:

    template<typename numberType, bool increaseByOne>
    numberType MyComputationClass<numberType, increaseByOne>::compute()
    {
        if constexpr (increateByOne)
            return a + b + 1;
        else
            return a + b;
    }
    
  • In C++20 you can use the requires clause:

    template<typename numberType, bool increaseByOne>
    class MyComputationClass
    {
       numberType a = 1;
       numberType b = 2;
       numberType compute() requires increaseByOne
       {
           return a + b + 1;
       };
        numberType compute() requires (!increaseByOne)
       {
           return a + b;
       };
    };
    
  • In old C++ in your case you can use simple if. Since increaseByOne is known at compile time the compiler will optimize it as if it were if constexpr. The only problem you would have is if you returned different types on each branch or have some code that is invalid on one of the branches. So simple if is a solution here:

    template<typename numberType, bool increaseByOne>
    numberType MyComputationClass<numberType, increaseByOne>::compute()
    {
        if (increateByOne)
            return a + b + 1;
        else
            return a + b;
    }
    
Jan Hackenberg
  • 481
  • 3
  • 14
bolov
  • 72,283
  • 15
  • 145
  • 224
  • thanks a lot for the answer. I was aware of the if constexpr, but my framework binds me to c++11 unfortunately. In fact I also messed up my question, I put correctly in an implementation header hpp. Corrected this in the question. I fear repeating the body or base class is both not so nice for my code, so I assume I will fall back kicking out the template bool again and just make it a member. Pay some computation overhead with normal if. Thanks a lot still, your answer is nice and clear, prevented me from trial and error. And it might help others. Bye – Jan Hackenberg Mar 20 '20 at 15:43
  • accepted your answer as well, as my question is gone, but not my problem unfortunately :) – Jan Hackenberg Mar 20 '20 at 15:44
  • @JanHackenberg there would be no computation overhead. I've edited the answer. – bolov Mar 20 '20 at 21:14
  • This is good to know, yesterday I made the flag a simply member and had it work at least. I might reintroduce the templated bool stuff then again. I call this code few billion times during optimization routine, and to optimize the if away might be a tiny bit runtime improvement. Thank you so much. I edited your answer, as your code fragment for old c++ still contained if const expression. – Jan Hackenberg Mar 21 '20 at 06:12