https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87709
--- Comment #4 from Baruch Burstein <bmburstein at gmail dot com> --- There is a pretty good (speculative) analysis of this issue here: https://stackoverflow.com/a/52986284/331785 I am copying it to here for completeness, but credit for this goes to the author of that post: There are two kinds of expressions that look similar but have vastly different meaning: (type) + expr (expr) + expr The first is a C-style cast expression, that converts the unary expression + expr to type, the second is a binary expression that performs addition. To disambiguate an expression of form (something) + expr, GCC first assumes that something is a type and does a tentative parse. If that succeeds, then the whole expression is treated as a cast expression, otherwise, something is reparsed as an expression. Now here's where I think the bug resides: during the tentative parse, GCC wrongly believes that class template argument deduction (CTAD) cannot appear, so it issues an error when it appears. But in fact, even though the tentative parse will definitely fail in this case, something may still be a valid function-style cast expression, and thus the reparse might be successful. For cat((lit('b')), lit('d')), lit('b') + lit('d'), and (lit('b')), GCC is clever enough to see that they can't be C-style cast expression, so it does not do the tentative parse. For (lit<char>('b')) + lit('d'), there's no CTAD in lit<char>('b'), so it is fine as well. Prove of the above analysis: If + is changed to / (or most operators other than -, * or &), no error occurs, because (something) / expr can't be a valid cast expression. Similar ambiguity exists in sizeof(something) (could be sizeof(type) or sizeof(expr)), and as expected, sizeof(lit(0)) triggers a similar error.