Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Argument-dependent lookup and function templates [duplicate]

Here is an example:

#include <string>
#include <algorithm>
#include <memory>

using std::string;

int main()
{
    string str = "This is a string";

    // ok: needn't using declaration, ADL works
    auto it = find(str.begin(), str.end(), 'i');

    // error: why ADL doesn't work?
    std::shared_ptr<string> sp = make_shared<string>(str);
}

When I tried to compile this program, the compiler complained:

error: no template named 'make_shared'; did you mean 'std::make_shared'?
        std::shared_ptr<string> sp = make_shared<string>(str); // error...
                                     ^~~~~~~~~~~
                                     std::make_shared

I guess the first function find doesn't need using declaration because of argument-dependent lookup(ADL): the compiler would search the namespace where string resides(i.e. std) for the definition of find. But for the second function make_shared, it seems that ADL doesn't work: I have to use std::make_shared or using declaration instead. I know the definitions of two function templates are different: the former takes one of its template paramters(typename T or something like that) as function parameter type and returns the same type. The latter takes function parameter pack as function paramter and its return type is another template parameter. Is this difference that disables ADL? Or could you help answer the question and offer some references?

like image 507
chihyang Avatar asked Dec 18 '15 09:12

chihyang


1 Answers

Argument-dependent lookup works for unqualified function call expressions. This is true for "normal" functions just as well as for function template specializations.

However, when you provide explicit template parameter for a template function, then the expression does not syntactically look like an function call:

foo<3>(x)  //   "foo less than three?"

That's why those cases don't trigger ADL. However, once a name is known to be a template, ADL does apply!

template <int> void foo();

foo<double, 5, T>(x);   // uses ADL
like image 106
Kerrek SB Avatar answered Sep 26 '22 14:09

Kerrek SB