consider the following code snippet (simplified from a more complex code):
#include <typeinfo>
#include <iostream>
struct A{
template<int S>
void print(){ std::cout << S << std::endl; }
};
struct B{};
template <class T>
A foo(int);
template<>
A foo<B>(int){ return A{}; }
template<class T>
int bar(int){
auto res = foo<T>(0);
std::cout << typeid(res).name() << std::endl;
res.print<5>(); // This line gives an error
return 0;
}
int main() {
bar<B>(0);
return 0;
}
If I try to compile it (either with gcc or clang) it results in the following error:
main.cpp:21:16: error: expected primary-expression before ')' token
21 | res.print<5>();
and I have to either:
res
as a A_int
objectprint()
using the template
keyword (res.template print<5>();
)in order to make this code compile.
I'm not really good in interpreting the Standard language, but as far as I understood the template
keyword in a function call is needed when invoking a template member function on an object which type explicitly depends on a template parameter (see for instance this question).
In this case, I didn't expect the keyword template
to be needed since res
should be an object of type A
, which is not explicitly dependent on a template parameter (even if it's the result of a template function call).
Could someone help me understanding where I'm wrong, and when the template
keyword is actually needed?
Thanks in advance, and apologise if this is a duplicate question, but I could not find anything specific for similar issues.
For all the compiler knows, somewhere in the program it has not yet seen there exists a specialization of foo
for some T
that returns something other than A
. So it cannot assume res
is always A
. Therefore, the type of res
does in fact depend on the template parameter T
, and then res.print
is a dependent name after all.
template
keyword is then required to let the compiler know that the angle bracket after print
is to be parsed as an angle bracket that forms part of a template-id, and not as a less-than operator.