显式实例化具有通用类型的函数模板

explicitly instantiate a function template with a generic type

我对 C++ 模板没有太多经验,所以我的术语可能不适用。请多多包涵,欢迎指正。

我有泛型 fixed_buf<N>:

// in foo.h
template <int N>
class fixed_buf {
 private:
  unsigned char data[N];
 public:
  const unsigned char* begin() const {
    return std::begin(data);
  }

  const unsigned char* end() const {
    return std::end(data);
  }
};

我想定义一个通用的 to_hex 函数

// in foo.h
template <typename T> std::string to_hex(const T& b);

// in foo.cpp
template <typename T> string to_hex(const T& b) {
  string r;
  hex(b.begin(), b.end(), back_inserter(r));
  return r;
}

使用显式实例化我也有以下内容:

// in foo.cpp
template string to_hex(const vector<unsign char>&);

我应该如何用 fixed_buf<N> 显式实例化 to_hex?可能吗?

"explicitly instantiate"

这意味着告诉编译器从具有某些指定类型的函数模板创建一个函数,即使它可能不需要(例如能够 link 反对它或减少编译时间) .

一个模板可以看作是一个"type level function"。您的 to_hex 接受某种类型作为参数,"returns" 接受某种类型的函数。

to_hex :: T -> to_hex<T>

你的fixed_buf也是类型级别的函数。它需要一些(编译时类型级别)整数和 returns 一个(结构)类型:

fixed_buf :: int(N) -> fixed_buf<N>

你不能"pass" fixed_bufto_hex;它不是类型而是类型级别的函数。您只能传递 fixed_buf 的结果。如果您不知道要传递给 fixed_buf 什么(类型级别)整数,那么您需要将其转换为(类型级别)函数:

\N -》 to_hex(fixed_buf(N)) :: int(N) -> to_hex<fixed_buf<N>>

虽然没有指定类型级别的整数,但它不是类型;并且只有类型(= 在这种情况下完全应用的模板)可以由编译器实例化。

因此您可以显式实例化 to_hex<fixed_buf<42>>(这是一个函数)而不是 to_hex<fixed_buf<N>>(模板)。

您可以显式实例化 to_hex<fixed_buf<1>>to_hex<fixed_buf<2>>、……不过;但我认为这样做不合理


如果你的意思不是实例化而是 "specialise" 那么再次不,你不能提供模板专业化,因为它需要是部分专业化(你不知道 N)这些不允许用于功能。解决方案:

  • 将实现放入模板中struct;他们可以部分专业化。

  • 使用重载:

    template <int N>
    string to_hex(const fixed_buf<N>& b) { /* implementation */ }
    

    这是一个应该可以工作的重载(不是部分特化;函数模板不允许这样做)。