8

我和一个朋友正在讨论 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)模板参数?

虽然编译它很简单,看看我们得到了什么,我们想知道是什么解决了歧义?

4

4 回答 4

7

AFAIK 它将被编译为new A<b>(c) > d. 这是解析它恕我直言的唯一合理方法。如果解析器在正常情况下不能假设 a > 结束一个模板参数,那将导致更多的歧义。如果你想要它,你应该写:

new A<(b > c)>(d);
于 2008-09-09T18:57:00.283 回答
6

正如 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"
于 2008-09-16T12:27:15.793 回答
3

C++ 标准定义,如果模板名称后跟 a <<则始终是模板参数列表的开头,而第一个非嵌套>的则作为模板参数列表的结尾。

如果您打算将>运算符的结果作为模板参数,那么您需要将表达式括在括号中。static_cast<>如果参数是一个或另一个模板表达式的一部分,则不需要括号。

于 2008-09-09T20:50:28.793 回答
0

词法分析器的贪婪可能是没有括号使其明确的决定因素。我猜词法分析器并不贪婪。

于 2008-09-09T18:18:18.630 回答