gpt4 book ai didi

c++ - 可以定义一个完全通用的 swap() 函数吗?

转载 作者:IT老高 更新时间:2023-10-28 12:30:01 24 4
gpt4 key购买 nike

以下片段:

#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 查找拖入?

最佳答案

  • unique_ptr<T>需要 T*成为 NullablePointer [unique.ptr]p3
  • NullablePointer需要 T* 的左值成为 Swappable [nullablepointer.requirements]p1
  • Swappable本质上需要 using std::swap; swap(x, y);x 选择过载, yT* 类型的左值[swappable.requirements]p3

在最后一步,您的类型 foo::bar产生歧义,因此违反 unique_ptr 的要求. libstdc++ 的实现是符合标准的,尽管我会说这相当令人惊讶。


措辞当然有点复杂,因为它是通用的。

[unique.ptr]p3

If the type remove_reference_t<D>::pointer exists, then unique_ptr<T, D>::pointer shall be a synonym for remove_reference_t<D>::pointer. Otherwise unique_ptr<T,
D>::pointer
shall be a synonym for T*. The type unique_ptr<T,
D>::pointer
shall satisfy the requirements of NullablePointer.

(强调我的)

[nullablepointer.requirements]p1

A NullablePointer type is a pointer-like type that supports null values. A type P meets the requirements of NullablePointer if:

  • [...]
  • lvalues of type P are swappable (17.6.3.2),
  • [...]

[swappable.requirements]p2

An object t is swappable with an object u if and only if:

  • the expressions swap(t, u) and swap(u, t) are valid when evaluated in the context described below, and
  • [...]

[swappable.requirements]p3

The context in which swap(t, u) and swap(u, t) are evaluated shall ensure that a binary non-member function named “swap” is selected via overload resolution on a candidate set that includes:

  • the two swap function templates defined in <utility> and
  • the lookup set produced by argument-dependent lookup.

请注意,对于指针类型 T* ,对于 ADL,相关的命名空间和类派生自类型 T .因此,foo::bar*foo作为关联的命名空间。 swap(x, y) 的 ADL其中xyfoo::bar*因此会找到 foo::swap .

关于c++ - 可以定义一个完全通用的 swap() 函数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36850522/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com