浮点的C ++模板专业化

Tim*_*ann 1 c++ templates specialization template-specialization c++17

我想专门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
  ...
};
Run Code Online (Sandbox Code Playgroud)

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);
};

...
Run Code Online (Sandbox Code Playgroud)

现在,类似于此答案,我将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);
};
Run Code Online (Sandbox Code Playgroud)

不幸的是,这导致以下编译器错误:

.../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 {
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                       ^
Run Code Online (Sandbox Code Playgroud)

有人可以向我解释我所缺少的吗?
提前致谢!

编辑:我们显式实例化cpp文件末尾的模板类,以便我们可以在cpp文件中执行模板代码。

Bar*_*rry 6

有人可以向我解释我所缺少的吗?

该错误说明了这一点:

... / x.cpp:46:56:错误:' X::bucket_width'的脱机定义的返回类型与声明中的不同

也就是说,该函数被声明为返回a,T但是您正在定义该函数以返回a 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;
  }
};
Run Code Online (Sandbox Code Playgroud)