c++ - 为什么我转发到单独命名空间中的 std::make_pair 不明确?

标签 c++ visual-c++ c++14

免责声明:这或多或少是出于教育目的,因此应忽略对所示包装的意义的讨论。

在其自己的命名空间中考虑以下模板:

// file my_make_pair.h

#pragma once
#include <utility>

namespace fc {

    template<typename T, typename U>
    decltype(auto) make_pair(T&& first, U&& second)
    {
        return std::make_pair(std::forward<T>(first),
                              std::forward<U>(second));
    }

}

当我尝试从这个命名空间中使用它时:

// file my_test.cpp

#include "my_make_pair.h"
#include <string>

namespace fc {

    void my_function(const std::string& name) {
        auto my_pair = make_pair(name, 42);
    }

}

我收到以下编译器错误:

could be 'decltype(auto) fc::make_pair<const std::string&,int>(T,U &&)'
    with
    [
        T=const std::string &,
        U=int
    ]

or 'std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,int> std::make_pair<const std::string&,int>(_Ty1,_Ty2 &&)'
                     [found using argument-dependent lookup]
    with
    [
        _Ty1=const std::string &,
        _Ty2=int
    ]

一旦我将包装器重命名为其他名称,例如make_my_pair,一切正常。

它似乎也与 fc::my_function 的常量引用参数有关,我将其用作该对的第一个值。当我将对包装器的调用更改为仅使用(原始)右值时,例如auto my_pair = fc::make_pair(1.42, 42);,一切正常。当我直接使用 std::make_pair 时,它也有效。

为什么编译器会首先考虑 std 命名空间的实现?我没有明确使用 std::make_pair(包装器定义除外),也没有在任何时候使用 using namespace std。我正在使用 Visual Studio 2015 (VC14)。

最佳答案

由于 Argument Dependent-name Lookup 调用不明确(日常事件能力)。因为你的论点是 std::string , 然后是 make_pair()在命名空间 std被考虑。

这就是为什么,例如,当您调用 std::cout << 21 时, 你不需要指定命名空间 std对于 operator<< : 由于 ADL,它由编译器计算。

如果你想强制使用你自己的实现,那么你需要在调用前加上命名空间 fc::make_pair(...) .

关于c++ - 为什么我转发到单独命名空间中的 std::make_pair 不明确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44129117/

相关文章:

c++ - Qt图形绘制

c++ - 分离的线程在退出时崩溃

c++ - 从具有相同容器类型但不同 value_type 的容器生成新类型

c++ - 为什么我的 C++ 可执行文件这么大?

C++ while循环,测试多个数组的下标

python - python 在 gdb 调试器中做了什么?

visual-studio-2010 - 无法获取 Mat 的列数和行数

c - __VA_ARGS__ 扩展使用 MSVC

c++ - 如何反转 `std::integer_sequence<int, 4, -5, 7, -3>` 中整数的顺序?

c++ - 非常量 constexpr 成员函数的用例?