【发布时间】:2014-04-23 16:51:15
【问题描述】:
我正在尝试理解一些递给我的递归 C++ 模板代码,但我遇到了一些奇怪的行为。出于某种原因,编译器似乎能够在编译时添加两个值,但必须在运行时进行左移。即便如此,只有在我尝试启用 c++11 的情况下才会出现问题。
代码(我已经简化,稍后您将看到)定义了两对模板——一对名为shft 和shft_aux,另一对名为add 和add_aux,它们以递归方式自行生成。顺便说一句,add 模板不应该是有用的,它的唯一目的是演示问题,而不是生成实际的 min 值。
如果我在没有命令行参数的情况下编译这段代码,它编译得很好。但是如果我指定-std=c++11 -stdlib=libc++,add_aux 上的static_assert 仍然可以,但是shft_aux 上的static_assert 现在会生成一个编译时错误,说static_assert expression is not an integral constant expression。
为什么左移与加法的处理方式不同?
谢谢, 克里斯
附言我用的是clang++版本Apple LLVM version 5.1 (clang-503.0.38) (based on LLVM 3.4svn)
#include <climits>
template <unsigned size> struct shft; // forward
template <unsigned size>
struct shft_aux
{
static const int min = shft<size>::min;
};
template <unsigned size>
struct shft
{
typedef shft_aux<size - 1> prev;
static const int min = prev::min << CHAR_BIT;
};
// Base specialization of shft, puts an end to the recursion.
template <>
struct shft<1>
{
static const int min = SCHAR_MIN;
};
// -----
template <unsigned size> struct add; // forward
template <unsigned size>
struct add_aux
{
static const int min = add<size>::min;
};
template <unsigned size>
struct add
{
typedef add_aux<size - 1> prev;
static const int min = prev::min + CHAR_BIT;
};
// Base specialization of add, puts an end to the recursion.
template <>
struct add<1>
{
static const int min = SCHAR_MIN;
};
// -----
int main()
{
static_assert(shft_aux<sizeof(int)>::min < 0, "min is not negative");
static_assert(add_aux<sizeof(int)>::min < 0, "min is not negative");
return 0;
}
【问题讨论】:
-
坦率地说,我不太明白你想用它做什么......也许你的问题有一个解决方案,而不仅仅是一些语言律师关于什么的评论标准允许。
-
这就像一个老笑话......“医生,我这样做的时候很痛”......“所以不要那样做!”现在我完全理解了这个问题,并且得到了标准的支持,我有信心提出一种不需要负数左移的不同方法来解决问题。
标签: c++ templates c++11 recursion clang++