C ++ шаблонная специализация для чисел с плавающей запятой - PullRequest
0 голосов
/ 24 мая 2018

Я хочу специализировать метод класса X для типов с плавающей точкой.Следующий код компилируется и отлично работает:

x.hpp:

template <typename T>
class X {
 public:
  ...
  T bucket_width(const BucketID index) const;
  T bucket_min(const BucketID index) const;
  T bucket_max(const BucketID index) const
  ...
};

x.cpp:

...

template <typename T>
T X<T>::bucket_width(const BucketID index) const {
  return bucket_max(index) - bucket_min(index) + 1;
};

template <>
float X<float>::bucket_width(const BucketID index) const {
  return bucket_max(index) - bucket_min(index);
};

template <>
double X<double>::bucket_width(const BucketID index) const {
  return bucket_max(index) - bucket_min(index);
};

...

Теперь аналогично этому ответу Я изменил файл cpp на:

template <typename T>
T X<T>::bucket_width(const BucketID index) const {
  return bucket_max(index) - bucket_min(index) + 1;
};

template <typename T>
std::enable_if_t<std::is_floating_point_v<T>, T> X<T>::bucket_width(const BucketID index) const {
  return bucket_max(index) - bucket_min(index);
};

К сожалению, это приводит к следующей ошибке компилятора:

.../x.cpp:46:56: error: return type of out-of-line definition of 'X::bucket_width' differs from that in the declaration
std::enable_if_t<std::is_floating_point_v<T>, T> X<T>::bucket_width(const BucketID index) const {
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                       ^

Может кто-нибудь объяснить мне, что мне не хватает?
Заранее спасибо!

Редактировать : Мы явно создаем экземпляры классов шаблонов в конце файла cpp, чтобы мы могли делать код шаблона в файле cpp.

1 Ответ

0 голосов
/ 24 мая 2018

Может кто-нибудь объяснить мне, что мне не хватает?

Ошибка объясняет это:

... / x.cpp: 46: 56: ошибка: возвращаемый тип внепланового определения 'X::bucket_width' отличается от того, что указано в объявлении

То есть объявлена ​​функция, возвращающая T, но выопределяя его, чтобы вернуть std::enable_if_t<std::is_floating_point_v<T>, T>.Те не соответствуют и должны.

В целом, вы пытаетесь частично специализировать шаблон функции, что невозможно.

Простое решение здесь заключается в использовании if constexpr:

template <typename T>
T X<T>::bucket_width(const BucketID index) const {
  if constexpr (std::is_floating_point_v<T>) {
    return bucket_max(index) - bucket_min(index);
  } else {
    return bucket_max(index) - bucket_min(index) + 1;
  }
};
...