依赖于参数的查找和函数模板

时间:2015-12-18 09:20:52

标签: c++ templates argument-dependent-lookup 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):编译器将搜索{{1}的命名空间} string)定义std。但对于第二个函数find,似乎make_shared无效:我必须使用ADLstd::make_shared声明。我知道两个函数模板的定义是不同的:前者将其模板参数之一(using或类似的东西)作为函数参数类型并返回相同的类型。后者将函数参数包作为函数参数,其返回类型是另一个模板参数。这种差异是否会导致typename T停用?或者你能帮忙回答这个问题并提供一些参考资料吗?

2 个答案:

答案 0 :(得分:1)

依赖于参数的查找适用于非限定函数调用表达式。对于&#34;正常&#34;这是正确的。函数以及函数模板特化。

但是,当您为模板函数提供显式模板参数时,表达式在语法上看起来不像函数调用:

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

这就是为什么这些案件不能触发ADL的原因。但是,一旦名称​​已知成为模板,ADL就会应用!

template <int> void foo();

foo<double, 5, T>(x);   // uses ADL

答案 1 :(得分:0)

当我们使用<>明确指定其模板参数时,模板方法不使用ADL,除非示波器中有可见的模板方法(具有相同的名称)。