c ++模板类成员函数专门化

c++ template class member function specialization

我有一个问题,我想在下面的代码中专门化模板类的模板成员函数。对于这个问题的答案,模板类成员函数的显式专门化似乎表明它不能完成。这是正确的吗?如果是的话,我是否可以在编译时通过内联inc函数进行扩展?

多谢!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <iostream>
#include <cstdio>

template <class IT, unsigned int N>
struct IdxIterator {
private:
  int startIdx[N], endIdx[N];  
  int curIdx[N];
  IT iter;

public:
  IdxIterator(IT it, int cur[], int start[], int end[]): iter(it) {
    for (int i = 0; i < N; i++) {
      curIdx[i] = cur[i];
      startIdx[i] = start[i];
      endIdx[i] = end[i];
    }
  }

  template <int dim>
  inline void inc() {
    curIdx[dim]++;
    if (curIdx[dim] > endIdx[dim]) {
      if (dim > 0) {
        curIdx[dim] = startIdx[dim];
        inc<dim-1>();
      }
    }
  }

  // how to declare this specialization?
  template <> template <>
  inline void inc<-1>() {
    std::cerr <<"IdxIterator::inc(" << -1 <<") dim out of bounds!
"
;
    throw 1;
  }

  inline IdxIterator<IT, N> operator++() {
    iter++;
    inc<N-1>();
    return *this;
  }

};

int main(int argc, char** argv) {

  int *buf = new int[100];
  int start[1], end[1];
  start[0] = 0; end[0] = 99;
  IdxIterator<int*, 1> it(buf, start, start, end);
  ++it;

  return 0;

}

G+++吐出:

test2.cpp:32:13: error: explicit specialisation in non-namespace scope
‘struct IdxIterator’ test2.cpp:32:25: error: explicit
specialisation in non-namespace scope ‘struct IdxIterator’
test2.cpp:33:23: error: template-id ‘inc<-0x00000000000000001>’ in
declaration of primary template test2.cpp: In member function ‘void
IdxIterator::inc() [with int dim = -0x000000000000003fe, IT =
int*, unsigned int N = 1u]’: test2.cpp:27:9: error: template
instantiation depth exceeds maximum of 1024 (use -ftemplate-depth= to
increase the maximum) instantiating ‘void IdxIterator::inc()
[with int dim = -0x000000000000003ff, IT = int*, unsigned int N = 1u]’
test2.cpp:27:9: recursively instantiated from ‘void IdxIterator::inc() [with int dim = -0x00000000000000001, IT = int*, unsigned
int N = 1u]’ test2.cpp:27:9: instantiated from ‘void IdxIterator::inc() [with int dim = 0, IT = int*, unsigned int N = 1u]’
test2.cpp:41:5: instantiated from ‘IdxIterator
IdxIterator::operator++() [with IT = int*, unsigned int N =
1u]’ test2.cpp:53:5: instantiated from here

test2.cpp: At global scope: test2.cpp:22:15: warning: inline function
‘void IdxIterator::inc() [with int dim = -0x000000000000003ff,
IT = int*, unsigned int N = 1u]’ used but never defined [enabled by
default]


在C++ 11中可能有更好的方法,但是您可以总是通过重载而不是专门化。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
template <int N>
struct num { };

class A
{
    template <int N>
    void f(num <N>) { };

    void f(num <-1>) { };

public:
    template <int N>
    void f() { f(num <N>()); };
};


在类外创建助手结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
template<dim>
struct inc {
template<class cur, end>
      inline static void foo(cur curIdx, end endIdx) {
        curIdx[dim]++;
    if (curIdx[dim] > endIdx[dim]) {
        inc<dim-1>::foo(curIdx, endIdx);
      }
    }    
};

template<>
struct inc<0> {
    template<class cur, end>
      inline static void foo(cur, end) {
       //terminate
    }    
};

class IdxIterator {
       template<int i>
       void inc() {
        static_assert(i > 0,"error out of bounds");
         int::foo(/*params*/);
    }

};

注意:如果您使用GCC,您可以使用cx1(0)强制内联。


您可以按照编译器错误消息的建议进行操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
template <class IT, unsigned int N>
struct IdxIterator {
private:
  template <int dim>
  inline void inc() {
    curIdx[dim]++;
    if (curIdx[dim] > endIdx[dim]) {
      if (dim > 0) {
        curIdx[dim] = startIdx[dim];
        inc<dim-1>();
      }
    }
  }
};

template <> template <>
inline void IdxIterator::inc<-1>() {
  std::cerr <<"IdxIterator::inc(" << -1 <<") dim out of bounds!
"
;
  throw 1;
}

IE将定义移动到命名空间范围。