题
我和一个朋友正在讨论 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)
模板参数?
虽然编译这个并看看我们得到什么是微不足道的,但我们想知道什么可以解决歧义?
解决方案
AFAIK 它将被编译为 new A<b>(c) > d
. 。恕我直言,这是解析它的唯一合理方法。如果解析器在正常情况下不能假设 > 结束模板参数,这将导致它更加模糊。如果你想要另一种方式,你应该写:
new A<(b > c)>(d);
其他提示
正如 Leon & 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"
C++ 标准定义,如果模板名称后跟 <
, , 这 <
始终是模板参数列表的开头和第一个非嵌套的 >
被视为模板参数列表的末尾。
如果您想要的结果是 >
运算符是模板参数,那么您需要将表达式括在括号中。如果参数是参数的一部分,则不需要括号 static_cast<>
或另一个模板表达式。
在没有括号使其显式的情况下,词法分析器的贪婪可能是决定因素。我猜词法分析器并不贪婪。
不隶属于 StackOverflow