0

以下のコードで、テンプレート クラスのテンプレート メンバー関数を特殊化したいという問題があります。テンプレートクラスメンバー関数の明示的な特殊化というこの質問に対する答えは、それができないことを示唆しているようです。それは正しいですか?もしそうなら、インライン inc 関数がコンパイル時に展開されるように使用できる回避策はありますか?

どうもありがとう!

#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!\n";
    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: エラー: 非名前空間スコープ 'struct IdxIterator' での明示的な特殊化 test2.cpp:32:25: エラー: 非名前空間スコープでの明示的な特殊化 'struct IdxIterator' test2.cpp:33:23:エラー: プライマリ テンプレート test2.cpp の宣言内のテンプレート ID 'inc<-0x00000000000000001>': メンバー関数 'void IdxIterator::inc() [with int dim = -0x000000000000003fe、IT = int*、unsigned int N = 1u ]': test2.cpp:27:9: エラー: テンプレートのインスタンス化の深さが最大の 1024 を超えています (最大値を増やすには -ftemplate-depth= を使用します) インスタンス化 'void IdxIterator::inc() [with int dim = -0x000000000000003ff, IT = int*, unsigned int N = 1u]' test2.cpp:27:9: 'void IdxIterator::inc() [with int dim = -0x00000000000000001, IT = int*, unsigned int N = 1u]' から再帰的にインスタンス化test2.cpp:27:9:'void IdxIterator::inc() [with int dim = 0, IT = int*, unsigned int N = 1u]' からインスタンス化されました test2.cpp:41:5: 'IdxIterator IdxIterator::operator++() からインスタンス化されました [with IT = int*, unsigned int N = 1u]' test2.cpp:53:5: ここからインスタンス化

test2.cpp: グローバル スコープ: test2.cpp:22:15: 警告: インライン関数 'void IdxIterator::inc() [with int dim = -0x000000000000003ff, IT = int*, unsigned int N = 1u]' が使用されましたが、未定義 [デフォルトで有効]

4

3 に答える 3

2

C++11 にはもっと良い方法があるかもしれませんが、特殊化の代わりにいつでもオーバーロードを行うことができます。

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>()); };
};
于 2013-09-19T11:35:39.367 に答える