为什么全局 merge() 函数与 std::merge() 冲突
Why does a global merge() function conflict with std::merge()?
请考虑以下代码:
#include <vector>
#include <algorithm>
template <typename Input1, typename Input2, typename Output>
void merge(Input1 begin1, Input1 end1, Input2 begin2, Input2 end2, Output out)
{
}
int main()
{
std::vector<int> a = {1, 2};
int b[] = {3, 4};
int c[4];
merge(a.begin(), a.end(), b, b + 2, c);
}
编译产量:
$ clang++ -std=c++11 -stdlib=libc++ merge.cpp
merge.cpp:15:5: error: call to 'merge' is ambiguous
merge(a.begin(), a.end(), b, b + 2, c);
^~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/algorithm:4056:1: note:
candidate function [with _InputIterator1 = std::__1::__wrap_iter<int *>,
_InputIterator2 = int *, _OutputIterator = int *]
merge(_InputIterator1 __first1, _InputIterator1 __last1,
^
merge.cpp:5:6: note: candidate function [with Input1 = std::__1::__wrap_iter<int
*>, Input2 = int *, Output = int *]
void merge(Input1 begin1, Input1 end1, Input2 begin2, Input2 end2, Output out)
^
1 error generated.
编译器版本:
$ clang++ --version
Apple LLVM version 5.0 (clang-500.2.78) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.0.0
Thread model: posix
为什么呼吁merge
模棱两可?不确定我的意思是::merge()
还是std::merge()
,尽管显然(?)它应该是::merge()
,因为我没有指定任何using
指令。我的merge
函数位于全局命名空间中,我认为它不会与std
命名空间中的任何内容冲突(因为这是命名空间的要点,对吧?如果我像其他数组一样将a
更改为int
数组,则编译时没有任何歧义。此外,添加冒号并调用::merge()
也可以正常工作。
所以我的问题是:这是 Clang 中的错误,还是我对命名空间有误解?为什么当两个函数不在同一命名空间中并且我没有使用任何using
指令使std::merge()
可见时,我对merge()
的调用会导致歧义?
问题是std::vector<T>::iterator
可能是一个类类型(在您的情况下,它是一个类类型):在重载解析期间,编译器会找到函数的所有可见声明。为此,它会在可能与其参数关联的命名空间中查找(这称为参数相关查找)。类型 std::vector<T>::iterator
在命名空间std
(或嵌套在其中的命名空间)中定义,因此,将考虑命名空间 std
中的函数进行重载解析。由于std::merge()
和你的merge()
都同样匹配,所以存在歧义。
避免此问题的最简单方法是为函数模板使用不同的名称。隐藏关联的命名空间是可能的,但并不容易:关联的命名空间取自定义类或类模板的位置以及其基类和模板参数。因此,为任何迭代器类型创建包装器模板是不够的,因为它仍然将原始命名空间与类型相关联。您可以尝试使函数模板更好地匹配,但鉴于它与标准算法一样通用,这也不太可行。
由于从std
命名空间对迭代器的参数依赖性查找(http://en.cppreference.com/w/cpp/language/adl)。
你可以写::merge
来只获取你的函数,但我宁愿使用不同的名称。
- 为什么在全局范围内使用"extern int a"似乎不行?
- 在全局变量中保存类的实例以重新创建类(创建"backup")
- 当vector是tje全局变量时,c++中vector的内存管理
- std::threads可以从Windows DLL中的全局变量创建/销毁吗?
- 如何创建一个空的全局类并在启动时实例化它
- 内联函数中具有内部链接的全局变量
- 为什么虚函数不能是静态的和全局的?
- 如何在信号处理程序和普通函数中对全局变量进行互斥读写操作
- 全局作用域中函数指针的赋值
- g++用户定义的动态链接库上的全局new和delete运算符
- 在命名空间中使用全局命名空间中的函数
- 全局变量 多读取器 一个写入器多线程安全?
- 类的全局对象和静态成员
- 如何声明一个可以在整个程序中使用的全局 2d 3d 4d .. 数组(堆版本)变量?
- 如果全局变量默认是外部变量,为什么要添加"extern"关键字?
- 不同作用域中的静态变量和全局变量
- 如何使用 llvm-10 库在C++定义 LLVM 全局值变量?
- 使用全局声明的向量时,C++双重释放错误/损坏
- 将线程中的数据存储到全局容器的最佳方法?
- 为什么全局 merge() 函数与 std::merge() 冲突