简体   繁体   English

C ++模板非类型参数算术

[英]C++ template nontype parameter arithmetic

I am trying to specialize template the following way: 我试图通过以下方式专门化模板:

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
};

however I get compiler message error 但是我得到编译器消息错误

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

what do my doing wrong? 我做错了什么? thanks 谢谢

I put workaround in comments. 我把解决方法放在评论中。 Apparently I cannot do arithmetic in template specialization? 显然我不能在模板专业化中做算术? seems counterintuitive. 似乎违反直觉。

here is my final solution in the problem to be solved. 这是我要解决的问题的最终解决方案。 Basically, consecutive index requires one multiplication only. 基本上,连续索引只需要一次乘法。

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 }

I am posting my solution is suggested by GMan 我发布我的解决方案是由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 }

Try something like this: 尝试这样的事情:

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

template<size_t _1>
struct integral_index_2 : public integral_index_<_1, _1+1> {
};

You can also move the condition from the primary template into the specialization. 您还可以将条件从主模板移动到专门化。 The trick is that while non-type parameters in sub-expressions aren't allowed in non-type specialization arguments, they are allowed in type arguments 诀窍是,虽然非类型特化参数中不允许子表达式中的非类型参数,但它们在类型参数中允许的

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
};

Occassionally, people also use SFINAE for this. 有时,人们也会使用SFINAE The following accesses ::type which is only there if the condition is true. 以下访问::type仅在条件为真时才存在。 If it is false, the type is not there and SFINAE sorts out the specialization. 如果它是假的,那里的类型不存在, 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
};

With enable_if being the following well-known template 使用enable_if是以下众所周知的模板

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

template<typename R = void>
struct enable_if<true, R> { typedef R type; };

我认为问题在于你试图通过价值而不是类型进行专业化......

Here's something that works for me: use a default argument for _2 instead of trying to specialize. 这是适合我的东西:使用_2的默认参数而不是尝试专门化。

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

Does that look like what you want? 这看起来像你想要的吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM