On 22 January 2016 at 17:11, John Marshall wrote: > The following code: > > template<class Tp, int Nm> inline Tp* end(Tp (&arr)[Nm]) { return arr + Nm; } > > struct S { int end; }; > bool negative(const S& s) { return s.end < 0; } > > template <typename T> bool tnegative(const T& t) { return t.end < 0; } > > produces a parse error misrecognising the final line's "end < 0" as a template: > > end3.cpp: In function ‘bool tnegative(const T&)’: > end3.cpp:6:61: error: parse error in template argument list > template <typename T> bool tnegative(const T& t) { return t.end < 0; } > ^~~~~~~ > > This message is from current trunk GCC, but similar error messages are produced by GCC 4.4 and 5.1. > > It seems clear to me that "t.end < 0" isn't supposed to be any kind of template invocation, so I was surprised by this message. Is there some standardese that I've missed that requires this to be parsed like this in a template function? Or is this a G++ parser bug? (I did a brief bugzilla search, but nothing similar leapt out at me.) This is a G++ bug, I'll report it to Bugzilla. Thanks for the minimal testcase. If t.end< was supposed to be the start of a template then it would be necessary to say "t.template end<" instead, to tell the parser to expect a template. In the absence of the "template" keyword G++ should assume otherwise, and parse it successfully as a less-than expression. > > (This is distilled down from https://bugs.debian.org/812294 in which code has an "end" field and is "using namespace std", and it appears that with GCC 6's C++14-by-default the field is colliding with some recentish std::end(). So various workarounds are available, probably starting with not using namespace std!) A workaround would be to change it to return (t.end) < 0;. The parentheses would stop the parser from doing the wrong thing.