依赖于参数的查找和函数模板
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
或类似的东西)作为函数参数类型,并返回相同的类型。后者以函数参数包作为函数参数,返回类型为另一个模板参数。这是禁用ADL
的区别吗?或者你能帮忙回答这个问题并提供一些参考资料吗?
参数相关查找适用于不合格的函数调用表达式。这对于"普通"函数和函数模板专门化都是正确的。
然而,当您为模板函数提供显式模板参数时,表达式在语法上看起来不像函数调用:
foo<3>(x) // "foo less than three?"
这就是为什么这些病例不会触发ADL。然而,一旦名称已知为模板,ADL就会适用!
template <int> void foo();
foo<double, 5, T>(x); // uses ADL
当我们用<>
显式指定模板参数时,模板方法不使用ADL,除非作用域中有可见的模板方法(同名)。
相关文章:
- 当函数模板参数是具有默认参数的类模板时,函数模板参数的推导如何执行
- 将重载的成员函数传递给函数模板
- C++17中函数模板中的静态数组初始化(MSVC 2019)
- 为什么 gcc 和 clang 为函数模板的实例化生成不同的符号名称?
- 具有常量引用参数的函数模板专用化
- std::span<const T> 作为函数模板中的参数
- 如何编写一个完美的缩写函数模板?
- 仅在函数模板中为那些定义了函数的类型执行函数
- 如何在C++中伪造虚拟可变参数函数模板?
- 以下代码中的函数模板有什么问题?
- 在 C++20 中是否不再允许在 std 中对程序定义类型的函数模板进行专用化?
- C++ 使用函数模板查找任何输入数据类型的中间值
- 函数模板查找问题
- 用于提升的基于模板的包装器函数:bimap 查找无法正常工作
- 为什么参数相关查找不适用于函数模板dynamic_pointer_cast
- 模板函数以查找C++中的子数组
- 依赖于参数的查找和函数模板
- 类中定义的友元函数模板是否可用于查找?clang++和g++不一致
- 在模板类的constexpr函数中查找正确的宏常量
- 模板化函数名查找难题(ADL)