Шаблонная специализация для одного из нескольких шаблонов в C ++ - PullRequest
2 голосов
/ 20 марта 2020

заголовок mycomputationclass.h:

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

#include mycomputationclass.hpp

файл реализации заголовка 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);
}

ошибка:

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

Все темы, связанные Для специализации я нахожу использование только одного шаблона. Может кто-нибудь помочь мне здесь?

1 Ответ

1 голос
/ 20 марта 2020

Прежде всего, пожалуйста, смотрите Почему шаблоны могут быть реализованы только в заголовочном файле? . Теперь ваша проблема не проистекает из вышесказанного, но, тем не менее, вам следует серьезно подумать, действительно ли вы хотите реализовать шаблон в файле cpp. Я подозреваю, что вы этого не делаете.

В любом случае проблема, о которой вы спрашиваете, заключается в том, что вы пытаетесь определить метод специализированного шаблона класса, который вы не специализировали.

Есть пара вариантов здесь.

  • Вы можете специализировать шаблон класса, повторяя все тело

    template<typename numberType>
    class MyComputationClass<numberType, true>
    {
       numberType a = 1;
       numberType b = 2;
       numberType compute();
    };
    
  • Вы можете создать шаблон базового класса с весь общий код и шаблоны производных классов только с теми частями, которые вам нужны для специализации

  • В C ++ 17 вы можете использовать if constexpr:

    template<typename numberType, bool increaseByOne>
    numberType MyComputationClass<numberType, increaseByOne>::compute()
    {
        if constexpr (increateByOne)
            return a + b + 1;
        else
            return a + b;
    }
    
  • В C ++ 20 вы можете использовать условие require:

    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;
       };
    };
    
  • В старом C ++ в вашем случае вы можете использовать простой if. Поскольку increaseByOne известно во время компиляции, компилятор оптимизирует его, как если бы это было if constexpr. Единственная проблема, с которой вы столкнетесь, - это если вы возвращали разные типы в каждой ветви или у вас был какой-то код, который недопустим в одной из ветвей. Так просто if это решение здесь:

    template<typename numberType, bool increaseByOne>
    numberType MyComputationClass<numberType, increaseByOne>::compute()
    {
        if (increateByOne)
            return a + b + 1;
        else
            return a + b;
    }
    
...