代码之家  ›  专栏  ›  技术社区  ›  tjwrona1992

“std::transform”编译时没有在多个编译器上查找限定名?[复制]

  •  0
  • tjwrona1992  · 技术社区  · 4 年前

    我在C++中编写了一个库,当我发现调用 std::transform std:: 命名空间前缀。根据C++文档 标准::转换 定义在 标准: 命名空间,因此在不完全限定名称的情况下不应编译它。

    #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;
            });
    }
    

    https://godbolt.org/ 而且它在其他编译器上似乎也没有出错!

    gcc example

    clang example

    MSVC example

    改变 transform 呼叫 ::transform 在全局命名空间中。

    我猜是在 <algorithm> 头文件有人不小心键入 using std::transform; 在全局命名空间中,这将使函数可以在不使用 前缀。。。但这将被认为是不好的做法,并且是标准库实现中的一个错误,不是吗?

    倍数 编译器!?即使是这样的窃听器,我怎么会去报告呢?

    1 回复  |  直到 4 年前
        1
  •  2
  •   Jerry Coffin    4 年前

    不,不是虫子

    当函数的参数位于特定的命名空间中时,编译器将在该命名空间中查找函数本身。

    在这种情况下,关系可能不明显,但函数的参数是什么 v.begin() 回报,大概是 std::vector<int>::iterator 2 ,因此编译器在命名空间中查找 std


    1然而,这是一个非常出乎意料的行为,一些人不仅会这样认为,而且还认为这是语言定义中的一个错误。