用于动态调度的部分模板特化

发布于 2024-07-13 15:53:13 字数 2076 浏览 14 评论 0原文

我正在尝试为基于整数值(而不是类型)模板化的函数编写动态调度程序。 虽然我可以编写代码生成器或使用大宏链来创建调度程序源,但模板化解决方案似乎会更优雅。

我已将调度程序简化为简单的形式(实际上并不执行任何调度):

// works fine with full template specialization
template <int N>
struct TestDispatcher1D {
  int f(int n) {
    if (n == N) return n; // replace me with actual dispatch
    TestDispatcher1D<N-1> t;
    return t.f(n);
  }
};

template<>
struct TestDispatcher1D<-1> {
  int f(int n) { return -1; }
};

// partial template specialization is problematic
template <int M, int N>
struct TestDispatcher2D {
  int f(int m, int n);
};

template<int M>
struct TestDispatcher2D<M,-1> {
  int f(int m, int n) { return -1; }
};

template<int N>
struct TestDispatcher2D<-1,N> {
  int f(int m, int n) { return -1; }
};

template<>
struct TestDispatcher2D<-1,-1> {
  int f(int m, int n) { return -1; }
};

template <int M, int N>
int TestDispatcher2D<M,N>::f(int m, int n) {
  if ((n == N) && (m == M)) return n + m; // replace me with actual dispatch
  if (m < M) {
    if (n < N) {
      TestDispatcher2D<M-1,N-1> t;
      return t(m,n);
    } else {
      TestDispatcher2D<M-1,N> t;
      return t(m,n);
    }
  } else {
    TestDispatcher2D<M,N-1> t;
    return t(m,n);
  }
}

// test code
void testIt() {
  { 
    TestDispatcher1D<16> t; 
    t.f(16); 
  }
  {
    TestDispatcher1D<16>t; 
    t.f(0);
  }
  {
    TestDispatcher2D<16,16>t; 
    t.f(8,8);
  }
}

在 gcc 4.1.1 上编译此程序时,出现以下错误:

t.cpp: In member function 'int TestDispatcher2D::f(int, int) [with int M = 16, int N = 16]':
t.cpp:63:   instantiated from here
t.cpp:40: error: no match for call to '(TestDispatcher2D) (int&, int&)'
t.cpp:63:   instantiated from here
t.cpp:43: error: no match for call to '(TestDispatcher2D) (int&, int&)'
t.cpp:63:   instantiated from here
t.cpp:47: error: no match for call to '(TestDispatcher2D) (int&, int&)'

显然,当我尝试创建递归对象时,编译器不会将此视为实例化新模板的请求。

有什么建议么?

I am attempting to write a dynamic dispatcher for a function that's templated on integer values (not on types). While I could either write a code generator or use a big macro chain to create the dispatcher source, it seems that a templated solution would be more elegant.

I've stripped down my dispatcher to a simple form (which doesn't actually do any dispatching):

// works fine with full template specialization
template <int N>
struct TestDispatcher1D {
  int f(int n) {
    if (n == N) return n; // replace me with actual dispatch
    TestDispatcher1D<N-1> t;
    return t.f(n);
  }
};

template<>
struct TestDispatcher1D<-1> {
  int f(int n) { return -1; }
};

// partial template specialization is problematic
template <int M, int N>
struct TestDispatcher2D {
  int f(int m, int n);
};

template<int M>
struct TestDispatcher2D<M,-1> {
  int f(int m, int n) { return -1; }
};

template<int N>
struct TestDispatcher2D<-1,N> {
  int f(int m, int n) { return -1; }
};

template<>
struct TestDispatcher2D<-1,-1> {
  int f(int m, int n) { return -1; }
};

template <int M, int N>
int TestDispatcher2D<M,N>::f(int m, int n) {
  if ((n == N) && (m == M)) return n + m; // replace me with actual dispatch
  if (m < M) {
    if (n < N) {
      TestDispatcher2D<M-1,N-1> t;
      return t(m,n);
    } else {
      TestDispatcher2D<M-1,N> t;
      return t(m,n);
    }
  } else {
    TestDispatcher2D<M,N-1> t;
    return t(m,n);
  }
}

// test code
void testIt() {
  { 
    TestDispatcher1D<16> t; 
    t.f(16); 
  }
  {
    TestDispatcher1D<16>t; 
    t.f(0);
  }
  {
    TestDispatcher2D<16,16>t; 
    t.f(8,8);
  }
}

When compiling this on gcc 4.1.1, I get the following errors:

t.cpp: In member function 'int TestDispatcher2D::f(int, int) [with int M = 16, int N = 16]':
t.cpp:63:   instantiated from here
t.cpp:40: error: no match for call to '(TestDispatcher2D) (int&, int&)'
t.cpp:63:   instantiated from here
t.cpp:43: error: no match for call to '(TestDispatcher2D) (int&, int&)'
t.cpp:63:   instantiated from here
t.cpp:47: error: no match for call to '(TestDispatcher2D) (int&, int&)'

Apparently, when I try to create the recursive objects, the compiler isn't treating this as a request to instantiate a new template.

Any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

在巴黎塔顶看东京樱花 2024-07-20 15:53:13

您根本没有在递归调用中调用 f() 函数,而是尝试“调用对象”:

您写道:

TestDispatcher2D<...> t;
return t(m,n);

但您想要:

TestDispatcher2D<...> t;
return t.f(m,n);

You're simply not calling the f() function in your recursive call, you're trying to "call the object":

You write:

TestDispatcher2D<...> t;
return t(m,n);

But you want:

TestDispatcher2D<...> t;
return t.f(m,n);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文