有效的C++03模板代码在C++11中无法编译

5

我在编写有效的C++03模板代码时遇到了一个小问题(虽然很容易解决),当使用C++11方言时,该代码将无法编译。

问题出现在模板参数解析处。让这段代码成为此问题的例子:

template <uint32_t number>
struct number_of_bits {
    enum  {
        value = 1 + number_of_bits<number >> 1>::value
    };
};

template <>
struct number_of_bits<0> {
    enum  {
        value = 0
    };
};

自从C++11允许">>"作为模板参数列表的结束符(如果该模板参数作为最后一个参数),当解析此代码时会产生问题。
我使用GCC(版本4.8.1)作为编译器,并且可以通过命令行正常编译:
g++ test.cc -o test

但是当我添加-std=c++11命令行开关时,它无法编译:

g++ -std=c++11 test.cc -o test

这是C++11的语言特性还是GCC中的一个bug?如果是后者,这是否是已知的bug?

1
你收到的确切错误信息是什么? - πάντα ῥεῖ
1
如果你能找到一些解析不正确而不是语法错误的东西,那就太酷了。 - user541686
@Mehrdad:我认为这会非常困难。在C++03中,>>必须关闭0个模板参数,但在C++11中关闭2个模板参数。我不确定如何在不导致C++11编译失败的情况下关闭C++03中未关闭的2个参数。 - nneonneo
能否在 C++03 和 C++11 中编写相同的 C++ 代码但执行不同的操作? - Shafik Yaghmour
1个回答

7

在使用-std=c++03模式时,Clang++会给我一个警告:

test.cpp:6:43: warning: use of right-shift operator ('>>') in template argument
      will require parentheses in C++11 [-Wc++11-compat]
        value = 1 + number_of_bits<number >> 1>::value
                                          ^
                                   (          )

事实上,在C++11中,解析规则已经修订,以使>>始终在模板上下文中关闭模板参数。正如警告所指出的那样,您只需要在参数周围加上括号即可解决解析问题:

value = 1 + number_of_bits<(number >> 1)>::value

这就是为什么Clang的诊断工具非常出色。我希望GCC也能有这样的工具,因为我每天都要使用它。 - dau_sama

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接