为什么对swap()的调用不明确
Why is this call to swap() ambiguous?
以下程序
#include <algorithm>
#include <utility>
#include <memory>
namespace my_namespace
{
template<class T>
void swap(T& a, T& b)
{
T tmp = std::move(a);
a = std::move(b);
b = std::move(tmp);
}
template<class T, class Alloc = std::allocator<T>>
class foo {};
}
int main()
{
my_namespace::foo<int> *a, *b;
using my_namespace::swap;
swap(a,b);
return 0;
}
导致g++
和clang
在我的系统上发出以下编译器错误:
$ clang -std=c++11 swap_repro.cpp -I.
swap_repro.cpp:28:3: error: call to 'swap' is ambiguous
swap(a,b);
^~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/bits/algorithmfwd.h:571:5: note: candidate function [with _Tp = my_namespace::foo<int, std::allocator<int> > *]
swap(_Tp&, _Tp&)
^
swap_repro.cpp:10:6: note: candidate function [with T = my_namespace::foo<int, std::allocator<int> > *]
void swap(T& a, T& b)
^
1 error generated.
$ g++ -std=c++11 swap_repro.cpp -I.
swap_repro.cpp: In function ‘int main()’:
swap_repro.cpp:28:11: error: call of overloaded ‘swap(my_namespace::foo<int>*&, my_namespace::foo<int>*&)’ is ambiguous
swap(a,b);
^
swap_repro.cpp:28:11: note: candidates are:
swap_repro.cpp:10:6: note: void my_namespace::swap(T&, T&) [with T = my_namespace::foo<int>*]
void swap(T& a, T& b)
^
In file included from /usr/include/c++/4.9/bits/stl_pair.h:59:0,
from /usr/include/c++/4.9/utility:70,
from /usr/include/c++/4.9/algorithm:60,
from swap_repro.cpp:1:
/usr/include/c++/4.9/bits/move.h:166:5: note: void std::swap(_Tp&, _Tp&) [with _Tp = my_namespace::foo<int>*]
swap(_Tp& __a, _Tp& __b)
^
我不明白为什么std::swap
被认为是候选过载,但这与foo
使用std::allocator<T>
有关。
消除foo
的第二个模板参数可以使程序编译时不会出错。
因为std::allocator<T>
用作模板类型参数,所以std
命名空间是ADL的关联命名空间。
〔basic.lookup.argdep〕/2,项目符号2,强调矿:
此外,如果
T
是类模板专用化,则其关联命名空间和类还包括:命名空间和类与为提供的模板参数的类型关联模板类型参数(不包括模板模板参数);任何模板模板参数都是其成员的命名空间;以及任何成员模板用作模板的类模板参数是成员。
并且指针具有与它们所指向的类型相同的一组关联的名称空间/类:
如果
T
是指向U
的指针或U
的数组,则其关联的命名空间和类是与CCD_ 13相关联的类。
关联名称空间的集合是根据参数类型中可见的各种类型确定的。值得注意的是,对于类模板,关联的名称空间包括所有模板参数的关联名称空间。当使用依赖于参数的查找来查找不合格的函数时,将搜索所有关联的命名空间。
foo<int>
的模板参数列表实际上是foo<int, std::allocator<int>>
,从而将名称空间std
拖到图片中,并且已经存在可用于swap()
的通用重载。
相关文章:
- C++ 编译器错误:P1LinkedList.cpp:145:错误:重载的"to_string(int&)"调用不明确
- 为什么调用不明确的 ctor 时没有编译时错误?
- G++ 错误:重载的"abs(无符号 int)"的调用不明确
- 如果存在具有不同参数的继承成员,为什么对 C++ 结构函数的调用不明确?
- 错误:重载'stoi(nlohmann::basic_json<>::value_type&)'的调用不明确
- 构建 castalia 时出错:重载函数的调用不明确
- 错误:重载的"abs(double)"调用不明确
- 结构构造函数调用不明确
- 错误:对重载函数的调用不明确
- 对重载'swap(char&, char&)'的调用不明确
- 对可变模板函数的调用不明确
- C++ 编译错误:重载的"<function_name>(char*&)"调用不明确
- VS2010中具有list_of的调用不明确
- 为什么这个运算符=调用不明确
- 为什么对重载函数的调用不明确
- C++中重载运算符函数对构造函数的调用不明确
- 为什么这些重载函数调用不明确
- 重载write(int)的调用不明确
- 带有重载r值引用函数的调用不明确
- 传递0而不是1时,sfinae调用不明确