【发布时间】:2016-08-19 10:21:10
【问题描述】:
下面的sn-p:
#include <memory>
#include <utility>
namespace foo
{
template <typename T>
void swap(T& a, T& b)
{
T tmp = std::move(a);
a = std::move(b);
b = std::move(tmp);
}
struct bar { };
}
void baz()
{
std::unique_ptr<foo::bar> ptr;
ptr.reset();
}
不为我编译:
$ g++ -std=c++11 -c foo.cpp
In file included from /usr/include/c++/5.3.0/memory:81:0,
from foo.cpp:1:
/usr/include/c++/5.3.0/bits/unique_ptr.h: In instantiation of ‘void std::unique_ptr<_Tp, _Dp>::reset(std::unique_ptr<_Tp, _Dp>::pointer) [with _Tp = foo::bar; _Dp = std::default_delete<foo::bar>; std::unique_ptr<_Tp, _Dp>::pointer = foo::bar*]’:
foo.cpp:20:15: required from here
/usr/include/c++/5.3.0/bits/unique_ptr.h:342:6: error: call of overloaded ‘swap(foo::bar*&, foo::bar*&)’ is ambiguous
swap(std::get<0>(_M_t), __p);
^
In file included from /usr/include/c++/5.3.0/bits/stl_pair.h:59:0,
from /usr/include/c++/5.3.0/bits/stl_algobase.h:64,
from /usr/include/c++/5.3.0/memory:62,
from foo.cpp:1:
/usr/include/c++/5.3.0/bits/move.h:176:5: note: candidate: void std::swap(_Tp&, _Tp&) [with _Tp = foo::bar*]
swap(_Tp& __a, _Tp& __b)
^
foo.cpp:7:10: note: candidate: void foo::swap(T&, T&) [with T = foo::bar*]
void swap(T& a, T& b)
我声明一个swap() 函数如此笼统以至于与std::swap 冲突,这是我的错吗?
如果是这样,有没有办法定义foo::swap(),这样它就不会被 Koenig 查找拖入?
【问题讨论】:
-
不能在 GCC 或 Clang 上编译,但可以在 MSVC 2015 上编译。也许是另一个未记录的特性。
-
该死,在不到第一个小时的时间内,这些都是一些不错的比率。 +16 票,观看 77 次,收藏 4 次。
-
你应该没有理由在一个只包含特定类型的非常特定的命名空间中定义这样一个通用的
swap模板。只需为foo::bar定义一个非模板swap重载。将常规交换留给std::swap,只提供特定的重载。 -
@TemplateRex
foo是我们在标准库上使用的间接层。我们支持的许多平台都有不完整/有缺陷的标准库,在这些平台上,我们将直接将foo::shared_ptr发送到boost::shared_ptr而不是std::shared_ptr。我们的一个平台有一个旧的std::swap(),它可以复制而不是移动,所以我们在foo中提供了一个替代品。 -
@TavianBarnes 我已经更新了我的答案,以回应您的两位 cmets。
标签: c++ c++11 gcc libstdc++ argument-dependent-lookup