Шаблон C++ не вводит арифметику параметра

Я пытаюсь специализироваться, обрабатывают следующий путь по шаблону:

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.

что делает мое выполнение неправильно?спасибо

Я поместил обходное решение в комментарии. По-видимому, я не могу сделать арифметики в шаблонной специализации? кажется парадоксальным.

вот мое конечное решение в проблеме, которая будет решена. В основном последовательный индекс требует одного умножения только.

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 }
6
задан Johannes Schaub - litb 11 April 2010 в 12:59
поделиться

5 ответов

Я публикую мое решение, предложенное 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 }
4
ответ дан 17 December 2019 в 02:26
поделиться

Попробуйте сделать что-нибудь вроде этого:

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

template<size_t _1>
struct integral_index_2 : public integral_index_<_1, _1+1> {
};
1
ответ дан 17 December 2019 в 02:26
поделиться

Вот кое-что, что работает для меня: используйте аргумент по умолчанию для _2 вместо того, чтобы пытаться специализировать.

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

Похоже ли это на то, что вы хотите?

0
ответ дан 17 December 2019 в 02:26
поделиться

Я думаю, проблема в том, что вы пытаетесь специализироваться по значению, а не по типу ...

0
ответ дан 17 December 2019 в 02:26
поделиться

Вы также можете перенести условие из первичного шаблона в специализацию. Хитрость в том, что хотя параметры не-типа в подвыражениях не допускаются в аргументах специализации не-типа, они допускаются в аргументах типа

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, который существует только в том случае, если условие истинно. Если оно ложно, то тип отсутствует, а 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; };
1
ответ дан 17 December 2019 в 02:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: