In answering this question, I came across this difference in behaviour with respect to template instantiation.
Initially there is a function template
template <typename T> void my_callback(void* data) { … }
Now something requires the address of this – specifically a void*, so the obvious approach is
bar(reinterpret_cast<void*>(&my_callback<int>));
However, with compiler versions pre gcc 4.5, this fails with a not-enough context… error. Fine – so the fix is to “cast” first – which forces instantiation, i.e:
void (*callback)(void*) = my_callback<int>;
bar(reinterpret_cast<void*>(callback));
This works fine.
Now the second scenario, rather than being a free function, it’s a static member of a class template, i.e.
template <typename T>
struct foo
{
static void my_callback(void* data) {
T& x = *static_cast<T*>(data);
std:: cout << "Call[T] with " << x << std::endl;
}
};
Now, the original reinterpret_cast works fine.
bar(reinterpret_cast<void*>(&foo<int>::my_callback));
So my question is – why this apparent difference in behaviour?
From n3290, 14.7.1 Implicit instantiation [temp.inst]
There are similar rules in paragraph 1 for class template specializations. Notice that the Standard speaks in terms of specialization because a specialization is implicitly declared when a template is used an no user-provided specialization is here, at least for function templates (paragraph 8).
Combined with paragraph 10,
I think the rule of thumb is: as soon as an object/class member/function is needed or to make the program otherwise work (speaking informally), the template is implicitly instantiated but no sooner. This include taking the address of a function.
As to the question you linked, some uses of
reinterpret_castmay make the program non-conformant, by which time it’s irrelevant to mention instantiations — I invite you to see my answer there</shameless>.