代码之家  ›  专栏  ›  技术社区  ›  Mr Fooz

动态调度的部分模板专用化

  •  2
  • Mr Fooz  · 技术社区  · 16 年前

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

    我将调度员简化为一个简单的表单(实际上不进行任何调度):

    // 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&)'
    

    显然,当我试图创建递归对象时,编译器并没有将其视为实例化新模板的请求。

    有什么建议吗?

    1 回复  |  直到 16 年前
        1
  •  1
  •   sth    16 年前

    你只是不打电话给 f() 函数在递归调用中,您试图“调用对象”:

    你写:

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

    但你想要:

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