Both of these lines make sense, but they mean very different things. It’s not always clear which way it should be parsed.

“Dot Template”

You’re less likely to see this problem, but I think it’s cool and has the same idea behind it. When your dependent name has a templated member function, the compiler gets confused about what you mean again:

Huh? template keyword? What’s happening is the compiler doesn’t know that m is a templated member function, we need tell it

v.template m<int>();

Alright so what’s the alternative here. Well, it’s a pretty well known issue with the C++ grammar that without context, you don’t know what certain lines mean. Borrowed from the D docs, consider the line:

A<B,C>D;

This could mean two things, (1) A is a templated class, B and C are template arguments, and D is a variable declared with that type. for example:

Or (2), A, B, C, and D are all variables and this is two comparisons separated by a comma

int A{}, B{}, C{}, D{};
(A < B), (C > D);

So, by default the compiler is assuming that m is not a template, which means that it assumes the angle brackets are less than and greater than operators, so it’s parsed as

((v.m) < int) > ();

This could make sense in a different context

template <typename T>
struct Obj {
int m;
};

And then the following:

int a{};
v.m<a>0;
((v.m < a) > 0

So the “dot template” is needed to say that what follows is a template. Like I said this is far less common, and the syntax is so awkward that it can drive design decisions. If you’ve ever wondered why std::get is a free function, a big part is that std::tuple is often used as a dependent type.