Is there some way to force C++ compilers to perform name lookup for a
given symbol during template instantiation (and not before)?
Yes. First of all, the name must be dependent. The name f
in wrapper
when used as f(t)
is dependent because t
is type-dependent. [temp.dep]/1:
In an expression of the form:
postfix-expression
(
expression-list opt )
where the postfix-expression is an unqualified-id, the
unqualified-id denotes a dependent name if
- any of the expressions in the expression-list is a pack expansion (14.5.3),
- any of the expressions in the expression-list is a type-dependent expression (14.6.2.2), or
- if the unqualified-id is a template-id in which any of the template arguments depends on a template parameter.
The problem is that names declared after the template itself, i.e. only in the instantiation but not the definition context, can solely be found using argument dependent name lookup. Your f
overloads only take fundamental types, but those do not have the global namespace associated with them according to [basic.lookup.argdep]/2:
If T
is a fundamental type, its associated sets of namespaces and
classes are both empty.
Thus the f
s you declared can never be found if the arguments are of the same type as the parameters. A little trick can help:
template <typename T>
struct refwrap
{
T&& t;
refwrap(T&& t) : t(std::forward<T>(t)) {}
operator T&&() {return std::forward<T>(t);}
};
template <typename T>
auto make_refwrap( T&& t ) -> refwrap<T> // making use of reference collapsing
{ return {std::forward<T>(t)}; } // inside refwrap to get forwarding
This template, when declared in the global namespace, will cause ADL to consider it. Rewrite wrapper
as follows:
template <class T>
auto wrapper( T t ) -> decltype( f( make_refwrap(t) ) )
{
return f( make_refwrap(t) );
}
Demo. This is not the proper way to do it though, as it will fail in more complex scenarios.
f
with a class template? That works, but I had hoped for a solution that would not require me to change the definition off
(a lot). Or did you have something else in mind? – Shanly