参数相关的查找和函数模板
Argument-dependent lookup and function templates
这是一个例子:
#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);
}
当我试图编译这个程序时,编译器报错:
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
我猜第一个函数 find
不需要 using
声明,因为参数依赖查找(ADL
):编译器会搜索 string
驻留(即 std
)用于 find
的定义。但是对于第二个函数 make_shared
,似乎 ADL
不起作用:我必须改用 std::make_shared
或 using
声明。我知道两个函数模板的定义是不同的:前者将其模板参数之一(typename T
或类似的东西)作为函数参数类型,而 returns 是同一类型。后者以函数参数包作为函数参数,其return类型是另一个模板参数。这种差异是否会导致 ADL
失效?或者你能帮忙回答问题并提供一些参考吗?
当我们使用 <>
明确指定其模板参数时,模板方法不使用 ADL,除非范围内有可见的模板方法(具有相同的名称)。
参数相关查找适用于非限定函数调用表达式。 "normal" 函数以及函数模板特化都是如此。
但是,当您为模板函数提供显式模板参数时,表达式在语法上看起来不像函数调用:
foo<3>(x) // "foo less than three?"
这就是为什么这些情况不会触发 ADL。但是,一旦名称 已知 可以作为模板,ADL 就适用了!
template <int> void foo();
foo<double, 5, T>(x); // uses ADL
这是一个例子:
#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);
}
当我试图编译这个程序时,编译器报错:
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
我猜第一个函数 find
不需要 using
声明,因为参数依赖查找(ADL
):编译器会搜索 string
驻留(即 std
)用于 find
的定义。但是对于第二个函数 make_shared
,似乎 ADL
不起作用:我必须改用 std::make_shared
或 using
声明。我知道两个函数模板的定义是不同的:前者将其模板参数之一(typename T
或类似的东西)作为函数参数类型,而 returns 是同一类型。后者以函数参数包作为函数参数,其return类型是另一个模板参数。这种差异是否会导致 ADL
失效?或者你能帮忙回答问题并提供一些参考吗?
当我们使用 <>
明确指定其模板参数时,模板方法不使用 ADL,除非范围内有可见的模板方法(具有相同的名称)。
参数相关查找适用于非限定函数调用表达式。 "normal" 函数以及函数模板特化都是如此。
但是,当您为模板函数提供显式模板参数时,表达式在语法上看起来不像函数调用:
foo<3>(x) // "foo less than three?"
这就是为什么这些情况不会触发 ADL。但是,一旦名称 已知 可以作为模板,ADL 就适用了!
template <int> void foo();
foo<double, 5, T>(x); // uses ADL