[英]C++ Template Ambiguity
A friend and I were discussing C++ templates. 我和朋友正在讨论C ++模板。 He asked me what this should do:
他问我应该做什么:
#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);
}
The last line in main has two reasonable parses. main中的最后一行有两个合理的解析。 Is 'b' the template argument or is
b > (c)
the template argument? 'b'是模板参数还是
b > (c)
模板参数?
Although, it is trivial to compile this, and see what we get, we were wondering what resolves the ambiguity? 虽然编译这个很简单,看看我们得到了什么,但我们想知道是什么解决了歧义?
As stated by Leon & Lee, 14.2/3 (C++ '03) explicitly defines this behaviour. 正如Leon&Lee所述,14.2 / 3(C ++ '03)明确定义了这种行为。
C++ '0x adds to the fun with a similar rule applying to >>
. C ++'0x通过适用于
>>
的类似规则增加了乐趣。 The basic concept, is that when parsing a template-argument-list a non nested >>
will be treated as two distinct >
>
tokens and not the right shift operator: 的基本概念,是解析模板参数列表的非嵌套时
>>
将作为两个不同待处理>
>
令牌而不是向右移位运算符:
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' and '#2' are equivalent in the above. “#1”和“#2”在上面等同。
This of course fixes that annoyance with having to add spaces in nested specializations: 这当然解决了必须在嵌套特化中添加空格的烦恼:
C<A<false>> c; // Parse error in C++ '98, '03 due to "right shift operator"
AFAIK it would be compiled as new A<b>(c) > d
. AFAIK它将被编译为
new A<b>(c) > d
。 This is the only reasonable way to parse it IMHO. 这是解析它的唯一合理方法恕我直言。 If the parser can't assume under normal circumstances a > end a template argument, that would result it much more ambiguity.
如果解析器在正常情况下无法假设>结束模板参数,那将导致更加模糊。 If you want it the other way, you should have written:
如果你想要另一种方式,你应该写:
new A<(b > c)>(d);
The C++ standard defines that if for a template name followed by a <
, the <
is always the beginning of the template argument list and the first non-nested >
is taken as the end of the template argument list. C ++标准定义如果对于模板名称后跟一个
<
,则<
始终是模板参数列表的开头,而第一个非嵌套的>
被视为模板参数列表的末尾。
If you intended that the result of the >
operator be the template argument, then you'd need to enclose the expression in parentheses. 如果您打算将
>
运算符的结果作为模板参数,那么您需要将表达式括在括号中。 You don't need parentheses if the argument was part of a static_cast<>
or another template expression. 如果参数是
static_cast<>
或其他模板表达式的一部分,则不需要括号。
The greediness of the lexer is probably the determining factor in the absence of parentheses to make it explicit. 词法分析器的贪婪可能是没有括号使其明确的决定因素。 I'd guess that the lexer isn't greedy.
我猜这个词法分析器并不贪心。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.