Templates are a hugely powerful feature of C++. They allow you to do so many different and cool things. Unfortunately, templates do have a bit of a reputation for having rather nasty syntax and for the most part this reputation is quite well deserved. This little quiz shows an example of some template syntax that you’ll only rarely come across but if you don’t know about it you could literally be left scratching your head in disbelieve, convinced you’ve uncovered a compiler bug.
Question: This code will fail to build on most compilers, why?
struct Bar { template void func() const { } template static void sfunc() { } }; template void Foo1(T const & t) { t.func(); T::sfunc(); } template void Foo2(T const * pT) { pT->func(); } int main() { Bar bar; Foo1(bar); Foo2(&bar); }
Answer: The compiler can’t figure out what t, T and pT are during the first pass template instantiation so you need to tell it that what follows is a template function. You do this using the ->template, .template and ::template operators.
struct Bar { template void func() const { } template static void sfunc() { } }; template void Foo1(T const & t) { t.template func(); //<--- The compiler doesn't know what t is, so you need to tell it T::template sfunc(); //<--- The compiler doesn't know what T is, so you need to tell it } template void Foo2(T const * pT) { pT->template func(); //<--- The compiler doesn't know what pT is, so you need to tell it } int main() { Bar bar; Foo1(bar); Foo2(&bar); }