我和朋友正在讨论C ++模板。他问我应该做些什么:
#include <iostream>
template <bool>
struct A {
A(bool) { std::cout << "bool\n"; }
A(void*) { std::cout << "void*\n"; }
};
int main() {
A<true> *d = 0;
const int b = 2;
const int c = 1;
new A< b > (c) > (d);
}
main中的最后一行有两个合理的解析。 'b'是模板参数还是b > (c)
模板参数?
虽然编译这个很简单,看看我们得到了什么,但我们想知道是什么解决了歧义?
答案 0 :(得分:6)
如Leon&amp;所述。 Lee,14.2 / 3(C ++ '03)明确定义了这种行为。
C ++'0x增加了适用于>>
的类似规则的乐趣。基本概念是,在解析模板参数列表时,非嵌套>>
将被视为两个不同的>
>
标记,而不是右移运算符:
template <bool>
struct A {
A(bool);
A(void*);
};
template <typename T>
class C
{
public:
C (int);
};
int main() {
A<true> *d = 0;
const int b = 2;
const int c = 1;
new C <A< b >> (c) > (d); // #1
new C <A< b > > (c) > (d); // #2
}
'#1'和'#2'在上面是相同的。
这当然解决了必须在嵌套特化中添加空格的烦恼:
C<A<false>> c; // Parse error in C++ '98, '03 due to "right shift operator"
答案 1 :(得分:5)
AFAIK它将被编译为new A<b>(c) > d
。这是解析它的唯一合理方法恕我直言。如果解析器在正常情况下不能假设&gt;结束模板参数,这会导致更加模糊。如果你想要另一种方式,你应该写:
new A<(b > c)>(d);
答案 2 :(得分:3)
C ++标准定义如果模板名称后跟<
,则<
始终是模板参数列表的开头,并且第一个非嵌套>
被采用作为模板参数列表的结尾。
如果您打算将>
运算符的结果作为模板参数,那么您需要将表达式括在括号中。如果参数是static_cast<>
或其他模板表达式的一部分,则不需要括号。
答案 3 :(得分:0)
词法分析器的贪婪可能是没有括号使其明确的决定因素。我猜lexer并不贪心。