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?
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With