6

次の方法でテンプレートを特殊化しようとしています。

template<size_t _1,size_t _2> // workaround: bool consecutive = (_1 == _2 - 1)>
struct integral_index_ {};
...
template<size_t _1>
struct integral_index_<_1, _1 + 1> { // cannot do arithmetic?
//struct integral_index_<_1, _2, true> { workaround
};

ただし、コンパイラメッセージエラーが発生します

the template argument list of the partial specialization includes a non
-type argument whose type depends on a template parameter.

私の何が間違っていますか?ありがとう

コメントに回避策を記載しました。テンプレート特化で算数できないらしい?直感に反するようです。

これが解決すべき問題の私の最終的な解決策です。基本的に、連続インデックスは 1 回の乗算のみが必要です。

130 template<size_t _1,size_t _2, bool consecutive = (_1 == _2 - 1)>
131 struct integral_index_ {
132     template<typename T, typename U>
133     __device__
134     static T eval(const T (&N)[4], const U &index) {
135         T j = index/N[_1];
136         return ((index - j*N[_1])*range<0,_1>::multiply(N) +
137                 j*range<0,_2>::multiply(N));
138     }
139 };
140
141 template<size_t _1,size_t _2>
142 struct integral_index_<_1, _2, true> {
143     template<typename T, typename U>
144     __device__
145     static T eval(const T (&N)[4], const U &index) {
146         return index*range<0,_1>::multiply(N);
147     }
148 };
149
150 template<size_t _1,size_t _2, typename T, typename U>
151 __device__
152 T integral_index(const T (&N)[4], const U &index) {
153     return integral_index_<_1,_2>::eval(N, index);
154 }
4

5 に答える 5

4

私は自分の解決策を投稿していますGManによって提案されています

130 template<size_t _1,size_t _2, bool consecutive = (_1 == _2 - 1)>
131 struct integral_index_ {
132     template<typename T, typename U>
133     __device__
134     static T eval(const T (&N)[4], const U &index) {
135         T j = index/N[_1];
136         return ((index - j*N[_1])*range<0,_1>::multiply(N) +
137                 j*range<0,_2>::multiply(N));
138     }
139 };
140
141 template<size_t _1,size_t _2>
142 struct integral_index_<_1, _2, true> {
143     template<typename T, typename U>
144     __device__
145     static T eval(const T (&N)[4], const U &index) {
146         return index*range<0,_1>::multiply(N);
147     }
148 };
149
150 template<size_t _1,size_t _2, typename T, typename U>
151 __device__
152 T integral_index(const T (&N)[4], const U &index) {
153     return integral_index_<_1,_2>::eval(N, index);
154 }
于 2010-04-11T04:46:19.770 に答える
1

次のようなことを試してください:

template<size_t _1,size_t _2>
struct integral_index_ {};

template<size_t _1>
struct integral_index_2 : public integral_index_<_1, _1+1> {
};
于 2010-04-11T03:06:50.050 に答える
1

条件をプライマリ テンプレートから特殊化に移動することもできます。秘訣は、部分式の非型パラメーターは非型特殊化引数で許可されていませんが、型引数では許可されていることです。

template<bool C> struct bool_ { };

template<int _1, int _2, typename = bool_<true> >
struct mapping {
  // general impl
};

template<int _1, int _2>
struct mapping<_1, _2, bool_<(_1 + 1) == _2> > {
  // if consecutive
};

template<int _1, int _2>
struct mapping<_1, _2, bool_<(_1 * 3) == _2> > {
  // triple as large
};

場合によっては、これにSFINAEを使用することもあります。次のアクセス::typeは、条件が true の場合にのみ存在します。false の場合、その型は存在せず、SFINAEは特殊化を分類します。

template<int _1, int _2, typename = void>
struct mapping {
  // general impl
};

template<int _1, int _2>
struct mapping<_1, _2, 
               typename enable_if<(_1 + 1) == _2>::type> {
  // if consecutive
};

template<int _1, int _2>
struct mapping<_1, _2, 
               typename enable_if<(_1 * 3) == _2>::type> {
  // triple as large
};

enable_if以下のよく知られたテンプレートで

template<bool C, typename R = void>
struct enable_if { };

template<typename R = void>
struct enable_if<true, R> { typedef R type; };
于 2010-04-11T12:37:32.833 に答える
0

問題は、タイプではなく値で特化しようとしていることだと思います...

于 2010-04-11T03:11:48.343 に答える
0

これは私にとってうまくいくものです:_2特殊化しようとする代わりに、デフォルトの引数を使用してください。

template <size_t _1, size_t _2 = _1 + 1>
struct integral_index_ {};

それはあなたが望むもののように見えますか?

于 2010-04-11T03:30:19.900 に答える