Cor*_*lks 5 c++ compiler-errors clang
请考虑以下代码:
#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);
}
Run Code Online (Sandbox Code Playgroud)
汇总收益率:
$ 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.
Run Code Online (Sandbox Code Playgroud)
编译器版本:
$ 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
Run Code Online (Sandbox Code Playgroud)
为什么呼吁merge含糊不清?我不确定我的意思,::merge()或者std::merge(),虽然明确(?)它应该是::merge()因为我没有指定任何using指令.我的merge函数在全局命名空间中,我认为它不会与std命名空间中的任何东西冲突(因为这是命名空间的主要点,对吧?).如果我像其他人一样a变成一个int数组,它编译时没有任何歧义.此外,添加冒号和调用::merge()工作正常.
所以我的问题是:这是Clang中的一个错误,还是我对命名空间有误解?merge()当两个函数不在同一个命名空间中并且我没有std::merge()用任何using指令可见时,为什么我的调用会导致歧义?
问题是std::vector<T>::iterator可能是类类型(在您的情况下,它是类类型):在重载解析期间,编译器会查找函数的所有可见声明.为此,它会查找可能与其参数相关联的名称空间(这称为参数依赖查找).类型std::vector<T>::iterator在命名空间std(或嵌套在其中的命名空间)中定义,因此,命名空间std中的函数被认为是重载决策.由于std::merge()和你们merge()两人的比赛同样好,所以存在歧义.
避免此问题的最简单方法是为函数模板使用不同的名称.隐藏关联的命名空间是可能的但不容易:关联的命名空间取自定义类或类模板的位置以及基类和模板参数.因此,为任何迭代器类型创建包装器模板是不够的,因为它仍然将原始命名空间与类型相关联.您可以尝试使您的函数模板更好地匹配,但考虑到它与标准算法一样通用,这也不太可行.
| 归档时间: |
|
| 查看次数: |
231 次 |
| 最近记录: |