Hey, fuckface! Think fast! template<typename F> void invokeFoo(F& f) { f.foo(); } struct Fooable { void foo() {} }; int main() { Fooable c; invokeFoo(c); } This is normal C++ code—nothing particularly nefarious afoot. invokeFoo is a function that takes a hopefully-fooable argument and, well, calls its foo method. That’s fine and well, but what if we further assume that F::foo is a member template? We might be tempted to write something like this: template<typename F, typename P> void invokeFoo(F& f) { f.foo<P>(); } struct Fooable { template<typename P> void foo() {} }; int main() { Fooable c; invokeFoo<Fooable, int>(c); } You might be surprised to know that this actually fails to compile. Here’s an excerpt of what GCC says: temp.cc: In function ‘void invokeFoo(F&)’: temp.cc:2:12: error: expected primary-expression before ‘>’ token 2 | f.foo<P>(); | ^ temp.cc:2:14: error: expected primary-expression before ‘)’ token 2 | f.foo<P>(); | ^ Hey, that’s a new one. A parse error? How? We didn’t even do anything particularly offensive here—or so one might think. Let me add some suggestive whitespace to imply a different parse: template<typename F, typename P> void invokeFoo(F& f) { f.foo < P > (); // ! } Does it make any god damn sense at all? No. But, you get the picture, I hope: that < could be a less-than comparison operator! That sounds dumb, right? I mean, if I write std::function<int()> f;, the compiler knows that I don’t mean to perform an ordering comparison as suggested by std::function < int() > f; (which would be valid for the right definitions of std::function and f!) because it looks up std::function, sees that it’s a template, and concludes that it should parse the stuff following it as a template parameter list. So, what’s the difference here? Well, in invokeFoo, f has type F, which could be anything! As such, there’s really no way to determine what F::foo might be. It doesn’t have to be a template! It could just be a regular old data member, in which case the...
First seen: 2025-12-12 06:40
Last seen: 2025-12-12 07:41