【发布时间】:2016-03-24 23:02:47
【问题描述】:
这是一个例子:
#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 或类似的东西)作为函数参数类型并返回相同的类型。后者将函数参数包作为函数参数,其返回类型是另一个模板参数。这是禁用ADL 的区别吗?或者您能帮忙回答问题并提供一些参考资料吗?
【问题讨论】:
-
第一个用法是脆的。您依赖于迭代器类型位于
std的未指定情况。如果在另一天迭代器类型是const char *,它将无法编译。 -
我知道省略
using声明是一种脆弱的方式。就像与第二个的比较一样>_ -
@chihyang:更好的例子是
begin(str)。 -
@chihyang:这根本不是我的意思。在您的示例中重要的是 iterator. 的类型
标签: c++ templates argument-dependent-lookup function-templates