使用 C++ 中的模板展开循环具有部分专业化
我正在尝试使用模板在 C++ 中展开循环,如下所示。
#include <iostream>
template< class T, T i >
struct printDown {
static void run(void) {
std::cout << i << "\n";
printDown< T, i - 1 >::run();
}
};
template< class T >
struct printDown< T, 0 > {
static void run(void) {
std::cout << 0 << "\n";
}
};
int main(void) {
printDown< int, 10 >::run();
return 0;
}
当我在 Cygwin 中使用 g++ 3.4.4 进行编译时,出现以下错误。
tmp.cpp:12: 错误:输入
T' of 模板参数
0'取决于 模板参数
我做错了什么?我是否需要以某种方式注释 0 来表明它是 T 类型?
提前致谢。
I'm trying to use templates to unroll a loop in C++ as follows.
#include <iostream>
template< class T, T i >
struct printDown {
static void run(void) {
std::cout << i << "\n";
printDown< T, i - 1 >::run();
}
};
template< class T >
struct printDown< T, 0 > {
static void run(void) {
std::cout << 0 << "\n";
}
};
int main(void) {
printDown< int, 10 >::run();
return 0;
}
When I compile w/ g++ 3.4.4 in Cygwin, I get the following error.
tmp.cpp:12: error: type
T' of
0' depends on
template argument
template parameter(s)
What am I doing wrong? Do I need to somehow annotate the 0 to say that it's of type T?
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您是否尝试过
int i
而不是T i
?Have you tried
int i
instead ofT i
?为什么会出现这种情况?从14.5.5/8开始,
因此,当您应用部分特化时,0 的类型是 T(取决于特化的参数)。有两种选择,一是使其不依赖,例如将 T i 更改为 int i,二是应用显式特化而不是部分特化。
这两个解决方案已经被其他人给出了,所以我不会在这里重新发布它们。至少你知道原因。它是由标准定义的。
Why this happens? From 14.5.5/8,
Therefore when you apply partial specialization, the type of 0 is T (dependent on a parameter of the specialization). There are two choices, one is to make it none dependent, e.g., change T i to int i, and second is to apply explicit specialization rather than partial specialization.
Both solutions have been given out by others, so I'm not gonna to repost them here. At least you know the reason. It's defined by standard.
正如
phooji
所指出的,您的实现遇到了一个小问题:它快速生成一长串调用,这将使编译器很快陷入困境。您可以通过使用二进制分解实现稍微复杂的版本来解决此问题。我也会让它在函子上通用,因为我很懒。
我们需要一个辅助模板,它保留要传递的参数的偏移量
并且您可以简单地实现
UnrolledLoop
:请注意,您可以为更多的
N
值提供专门化(3,例如 4)对编译器更好。As pointed out by
phooji
your implementation suffers from a small issue: it quickly generates a long list of calls, which will make compilers choke quickly.You could work around this by implementing a slightly more complicated version, using binary decomposition. I'll make it generic on a functor too, cause I am lazy.
We need a helper template, which keeps an offset of the parameter to pass
And you can implement
UnrolledLoop
simply:Note that you could provide specialization for more values of
N
(3, 4 for example) to be nicer on the compiler.将其添加到您的示例中怎么样:
如果事先不知道 T 的类型,编译器无法自动将 0 转换为 int 。
What about adding this to your example:
The compiler cannot cast 0 to int automatically without knowing T's type in advance.
刚刚发现这个。显然人们可以做这样的事情。
我不知道可以做到这一点。非常 Prologish 和很不错。
Just found this out. Apparently one can do something like this.
I had no idea that could be done. Very Prologish & very nice.
您可以将参数设置为类型参数来解决此问题,
这样您就可以在部分特化中指定所需的任何条件。
You can make the parameter a type parameter to work this around
This way you can specify any conditions you want in the partial specializations.