<utility> 执行 swap() 时不一定包含 - 这怎么会成为问题?
<utility> not necessarily included when swap() is performed - How can this become a problem?
正在阅读C++ named requirements: Swappable我遇到了以下注释
It is unspecified whether <utility>
is actually included when the standard library functions perform the swap, so the user-provided swap() should not expect it to be included.
假设我有一个 user-defined 类型 class Foo
和一个 user-provided swap()
。我想为我的 class Foo
使用标准库算法,该算法与
执行交换
using std::swap;
swap(arg1, arg2);
如 above-mentioned cppreference 文章中所述,以及我必须
#include
使用此算法不会 #include <utility>
。
如果我在 swap()
中依赖 <utility>
提供的功能,这怎么会导致问题?我必须在定义我的 swap()
的文件中 #include <utility>
自己。该场景应类似于以下内容:我有一个文件,其中 #includes
我的 class Foo
和我的 user-provided swap()
以及我使用的算法的 header .因此,关于算法是否 #include <utility>
永远不会有问题。
我可能对 #include
和编译在某些不同情况下如何相互作用有误解。哪种情况可能会导致编译问题?
简短的回答是,如果没有明确的 #include <utility>
,如果 Foo
没有自定义 swap
,则无法保证 std::swap
回退;导致编译错误。
如果代码中某处有 using std::swap;
语句 - 您的代码或算法内部 - 则必须已经包含 std::swap
函数,否则会出现编译错误。
cppreference 指出的是,无法保证 std::foo_algorithm
将包含 <utility>
并在调用 swap(a,b)
之前使用 using std::swap;
构造。请注意,它使用不合格的名称进行交换。
这意味着如果您的 class 依赖于 std::swap
的存在,因为它缺少任何自定义 swap
函数,那么调用 std::foo_algorithm
可能会导致编译错误说由于 std::swap
未被自动包含,因此没有合适的 swap(Foo&,Foo&)
函数。简单的解决方法是将 #include <utility>
放在 #include <foo_algorithm>
.
之前
但是,如果您有一个自定义交换并且算法可以找到它(因为它要么直接包含在当前命名空间中,要么因为 ADL 启动),一切都可以正常编译。与此无关,无论如何,您的交换应该使用 using std::swap; swap(a,b);
构造,因此如果您的 swap
存在,则 std::swap
可能始终存在。
让我们试着理解你从 cppreference 引用的注释。
It is unspecified whether <utility>
is actually included when the standard library functions perform the swap, so the user-provided swap() should not expect it to be included.
例如,std::sort
可以执行交换。要使用 std::sort
,您需要包含 <algorithm>
。该声明基本上说,尽管如此,<algorithm>
可能没有包含 <utility>
。因此下面的代码可能有问题。
#include <algorithm>
int main() {
int arr[] = { 4, 1, 7 };
std::sort(arr, arr + 3);
std::swap(arr[0], arr[1]); // may error out here
}
这是违反直觉的,因为 std::sort
在内部执行 std::swap
。 为了安全起见,如果需要 std::swap
,请始终明确包含 <utility>
。不要假设其他一些使用 std::swap
的标准库头文件本身包含了 <utility>
。 以下代码应该始终有效,而 #include <utility>
乍一看似乎没有必要.
#include <algorithm>
#include <utility>
int main() {
int arr[] = { 4, 1, 7 };
std::sort(arr, arr + 3);
std::swap(arr[0], arr[1]);
}
正在阅读C++ named requirements: Swappable我遇到了以下注释
It is unspecified whether
<utility>
is actually included when the standard library functions perform the swap, so the user-provided swap() should not expect it to be included.
假设我有一个 user-defined 类型 class Foo
和一个 user-provided swap()
。我想为我的 class Foo
使用标准库算法,该算法与
using std::swap;
swap(arg1, arg2);
如 above-mentioned cppreference 文章中所述,以及我必须
#include
使用此算法不会 #include <utility>
。
如果我在 swap()
中依赖 <utility>
提供的功能,这怎么会导致问题?我必须在定义我的 swap()
的文件中 #include <utility>
自己。该场景应类似于以下内容:我有一个文件,其中 #includes
我的 class Foo
和我的 user-provided swap()
以及我使用的算法的 header .因此,关于算法是否 #include <utility>
永远不会有问题。
我可能对 #include
和编译在某些不同情况下如何相互作用有误解。哪种情况可能会导致编译问题?
简短的回答是,如果没有明确的 #include <utility>
,如果 Foo
没有自定义 swap
,则无法保证 std::swap
回退;导致编译错误。
如果代码中某处有 using std::swap;
语句 - 您的代码或算法内部 - 则必须已经包含 std::swap
函数,否则会出现编译错误。
cppreference 指出的是,无法保证 std::foo_algorithm
将包含 <utility>
并在调用 swap(a,b)
之前使用 using std::swap;
构造。请注意,它使用不合格的名称进行交换。
这意味着如果您的 class 依赖于 std::swap
的存在,因为它缺少任何自定义 swap
函数,那么调用 std::foo_algorithm
可能会导致编译错误说由于 std::swap
未被自动包含,因此没有合适的 swap(Foo&,Foo&)
函数。简单的解决方法是将 #include <utility>
放在 #include <foo_algorithm>
.
但是,如果您有一个自定义交换并且算法可以找到它(因为它要么直接包含在当前命名空间中,要么因为 ADL 启动),一切都可以正常编译。与此无关,无论如何,您的交换应该使用 using std::swap; swap(a,b);
构造,因此如果您的 swap
存在,则 std::swap
可能始终存在。
让我们试着理解你从 cppreference 引用的注释。
It is unspecified whether
<utility>
is actually included when the standard library functions perform the swap, so the user-provided swap() should not expect it to be included.
例如,std::sort
可以执行交换。要使用 std::sort
,您需要包含 <algorithm>
。该声明基本上说,尽管如此,<algorithm>
可能没有包含 <utility>
。因此下面的代码可能有问题。
#include <algorithm>
int main() {
int arr[] = { 4, 1, 7 };
std::sort(arr, arr + 3);
std::swap(arr[0], arr[1]); // may error out here
}
这是违反直觉的,因为 std::sort
在内部执行 std::swap
。 为了安全起见,如果需要 std::swap
,请始终明确包含 <utility>
。不要假设其他一些使用 std::swap
的标准库头文件本身包含了 <utility>
。 以下代码应该始终有效,而 #include <utility>
乍一看似乎没有必要.
#include <algorithm>
#include <utility>
int main() {
int arr[] = { 4, 1, 7 };
std::sort(arr, arr + 3);
std::swap(arr[0], arr[1]);
}