C++ Template Ambiguity

半城伤御伤魂 提交于 2019-12-19 02:18:27

问题


A friend and I were discussing C++ templates. 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. Is 'b' the template argument or is b > (c) the template argument?

Although, it is trivial to compile this, and see what we get, we were wondering what resolves the ambiguity?


回答1:


AFAIK it would be compiled as 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);



回答2:


As stated by Leon & Lee, 14.2/3 (C++ '03) explicitly defines this behaviour.

C++ '0x adds to the fun with a similar rule applying to >>. 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.

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"



回答3:


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.

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.




回答4:


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.



来源:https://stackoverflow.com/questions/52506/c-template-ambiguity

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!