Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Template code won't compile (Deferred lookup)

I have two strange cases where it seems like code should compile, but it doesn't. To start, consider the code below, which compiles successfully:

struct A
{
    template <class T>
    void member_func(T t)
    {
        global_func(t);
    }
};

int main()
{
}

But if I fully-qualify global_func by prefixing with "::", it doesn't compile with error "'global_func' was not declared in this scope":

struct A
{
    template <class T>
    void member_func(T t)
    {
        ::global_func(t);
    }
};

int main()
{
}

Also, if I try to pass global_func to boost::bind, it doesn't compile (same error):

#include <boost/bind.hpp>

class A
{
    template <class T>
    void member_func(T t)
    {
        boost::bind(global_func)(t);
    }
};

int main()
{
}

Why doesn't it compile in these cases? It seems like the member_func() template method isn't instantiated, so it shouldn't find the missing function error.

like image 649
Kyle Simek Avatar asked Dec 27 '22 10:12

Kyle Simek


1 Answers

In the first example global_func is a dependent name because it is an unqualified name used in a postfix () expression where the expression in parentheses depends on a template parameter. This means that lookup must be deferred until the point that the template is instantiated where the template parameter is known and ADL may have an effect.

In the second example ::global_func is a qualified name so its lookup is not deferred and it must be looked up at the pointer where the template is defined.

Similarly, in the expression boost::bind(global_func), global_func is not used in an expression which depends on the template parameter so, again, lookup is not deferred and a declaration must be visible at the point of definition of the member template.

like image 142
CB Bailey Avatar answered Jan 07 '23 23:01

CB Bailey