我想了解一些我遞過來的遞歸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;
}
這就像那個老笑話......「醫生,當我這樣做的時候會很痛苦......」「所以不要這樣做!」既然我完全理解了這個問題,並有了標準的支持,我就有信心提出一種解決問題的不同方式,而不需要左移負數。 –