c++ - 定义使用此类型作为模板参数的类型和函数

标签 c++

我正在制作在 CPU 上生成 mip 映射的函数。 我的目标是编写适用于许多 DXGI_FORMAT 的通用函数。函数对所有 DXGI_FORMAT 组合做同样的事情,唯一的区别是数据类型和加载和存储它的 XMMATH 函数。

我尝试以一种很好的方式做到这一点——通过模板参数,就像那样:

#define AVERAGE(p, q) (((p - q) * 0.5f) + q)

template<typename XMATH_PIXEL_FORMAT,
         typename XMVECTOR(*XMATH_LOAD_FUNC)(const XMATH_PIXEL_FORMAT*),
         typename void(*XMATH_STORE_FUNC)(XMATH_PIXEL_FORMAT*, XMVECTOR)>
void minifyMipMap(XMATH_PIXEL_FORMAT* dst, const XMATH_PIXEL_FORMAT* src, size_t src_x, size_t src_y) {
  size_t x, y, x2, y2, dst_x = src_x >> 1, dst_y = src_y >> 1;
  XMVECTOR out, p00, p10, p01, p11; // p:xy

  for(y = 0; y < dst_y; ++y) { // for each dst line
    y2 = y << 1; // y2 = y * 2
    for(x = 0; x < dst_x; ++x) { // for each dst pixel
      x2 = x << 1; // x2 = x * 2

      // load 4 pixels
      p00 = XMATH_LOAD_FUNC(src + y2 * src_x + x2);
      p10 = XMATH_LOAD_FUNC(src + y2 * src_x + x2 + 1);
      p01 = XMATH_LOAD_FUNC(src + (y2 + 1) * src_x + x2);
      p11 = XMATH_LOAD_FUNC(src + (y2 + 1) * src_x + x2 + 1);

      // blend 4 pixels into 1
      out = AVERAGE(AVERAGE(p00, p10), AVERAGE(p01, p11));

      // store dest pixel
      XMATH_STORE_FUNC(dst + y * dst_x + x, out);
    }
  }
}


void test() {
  BYTE src[] = {
    0, 0, 0, 255, // black
    255, 255, 255, 255, // white
    0, 0, 0, 255, // black
    255, 255, 255, 255 // white
  };
  XMUBYTE4 dst[1]; // gray ???

  minifyMipMap<XMUBYTE4, XMLoadUByte4, XMStoreUByte4>(dst, (const XMUBYTE4*)src, 2, 2); // 2x2 = > 1x1
}

msvc 说:C2893:无法专门化函数模板 'void minifyMipMap(XMATH_PIXEL_FORMAT *,const XMATH_PIXEL_FORMAT *,size_t,size_t)' 使用以下模板参数: 'DirectX::PackedVector::XMUBYTE4'

我尝试以几种组合方式编译此代码,但没有成功(我也尝试将类型定义为类模板并将函数定义为此类的静态方法参数,但它也失败了)。 我希望以某种方式可以在 C++ 中以很好的方式编写它——无需使用#define

最佳答案

如果你想接受任意函数,不要这样做。接受每个不同函数的单个模板参数。

template<typename Func>
void foo(Func f) {
  // call f in any way you need
  f();
}

// can be used like this with functions
void bla() {}
f(&bla);
// Functors
struct X { void operator()() {} }
f(X());

如果传递的函数无法以您的代码调用它的方式调用,编译器会报错。

如果您想真正帮助您的用户,您可以使用 static_assert 和一些元编程提供一些有限形式的概念检查。

关于c++ - 定义使用此类型作为模板参数的类型和函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21661208/

相关文章:

c++ - 无法将循环的输出写入文件

c++ - 实现简单的分配器

c++ - 无法从 friend 类访问私有(private)和公共(public)成员

c++ - 如何在 Observer 中处理具有不同状态值类型的 Observable

c++ - ctrl+alt+del 禁止在window操作系统中使用c

c++ - 在创建结构时修改类私有(private)成员 (C++)

c++ - 当我获得指向智能指针的指针时,是否需要释放内存?

c++ - 如何从Syslog-NG/Syslog获取数据

C++插入数字直到某个符号

类继承的C++问题