Consider some function template such as:
template <class T>
const auto& foo() { static T t; return t; }
The definition would not be valid if T were to be void. Nonetheless, we are allowed to instantiate the declaration alone without triggering an error:
extern template const auto& foo<void>(); // explicit instantiation declaration
Now let's consider situations where foo is called, rather than being explicitly instantiated. Obviously, if foo is ever called in an evaluated context, the definition of the specialization will be instantiated. What about in an unevaluated context? We know that if a function template with a non-deduced return type is called in an unevaluated context, the definition of the specialization is not instantiated. The obvious example of this is std::declval<T>. It's not clear whether the same is possible for a function that has a deduced return type.
For example, I considered this:
static_assert(sizeof( (void)foo<void>(), char{} ) == 1);
However, even in this situation, where the compiler definitely has enough information to evaluate the sizeof expression without knowing the return type, a compilation error still occurs (godbolt link).
- What provision of the Standard requires the instantiation of the definition of
foo<void>in this situation? - Is there any way that
foo<void>can be called inside an unevaluated expression that would not instantiate its definition?