【发布时间】:2021-01-31 12:25:47
【问题描述】:
当我发现对std::transform 的调用没有完全限定具有std:: 命名空间前缀的调用时,我正在用C++ 编写一个库。根据 C++ 文档,std::transform 是在 std:: 命名空间中定义的,因此如果没有完全限定名称,则不应编译。
#include <algorithm>
#include <vector>
int main()
{
std::vector<int> v{ 1, 2, 3 };
// "transform" is supposed to be in the namespace "std::"???
transform(v.begin(), v.end(), v.begin(), [](const auto& value) {
return value + 1;
});
}
起初我认为这是标准库的 Microsoft 实现中的一个错误,因为我在 Visual Studio 中工作,但后来我在 https://godbolt.org/ 上使用一堆不同的编译器对其进行了测试,它似乎编译没有错误也可以在其他编译器上使用!
将transform 调用更改为::transform 会导致编译失败,因此很明显全局命名空间中没有transform 的符号。
我的猜测是,在 <algorithm> 头文件的某个地方,有人不小心在全局命名空间中键入了 using std::transform;,这将使函数可以在没有 std:: 前缀的情况下调用......但这将被认为是不好的做法,并且会是标准库实现中的一个错误,不是吗?
我是不是在多个编译器的标准库实现中发现了一个错误!?如果是这样,我什至会如何报告这样的错误?
【问题讨论】:
-
它被称为“参数依赖查找”。在与任何函数参数关联的命名空间中查找未限定的函数名称。在这种情况下,
v.begin()有一些迭代器类型std::something 。这就是重载运算符调用的工作原理
标签: c++ gcc visual-c++ namespaces clang