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?
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);
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"
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With