我想了解一些我递过来的递归C++模板代码,并且我遇到了一些奇怪的行为。出于某种原因,编译器似乎能够在编译时添加两个值,但是必须在运行时留下左移。即使如此,只有在尝试使用C++ 11进行构建时才会出现问题。使用C++ 11时,C++递归模板的奇怪行为
的代码(我已经煮下来,以后你会看到)定义2对模板 - 一对名为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
。
为什么左移与加法不同?
谢谢, 克里斯
附:我使用铛++版本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;
}
这就像那个老笑话......“医生,当我这样做的时候会很痛苦......”“所以不要这样做!”既然我完全理解了这个问题,并有了标准的支持,我就有信心提出一种解决问题的不同方式,而不需要左移负数。 –