如何为我的班级提供交换功能?
在 STL 算法中启用交换
的正确方法是什么?
1) 会员交换
。 std::swap
是否使用 SFINAE 技巧来使用成员 swap
。
2) 在同一命名空间中独立的交换
。
3) std::swap
的部分特化。
4)以上所有。
谢谢。
编辑:看来我没有清楚地表达我的问题。基本上,我有一个模板类,我需要 STL 算法来使用我为该类编写的(高效)交换方法。
What is the proper way to enable my swap
in STL algorithms?
1) Member swap
. Does std::swap
use SFINAE trick to use the member swap
.
2) Free standing swap
in the same namespace.
3) Partial specialization of std::swap
.
4) All of the above.
Thank you.
EDIT: Looks like I didn't word my question clearly. Basically, I have a template class and I need STL algos to use the (efficient) swap method I wrote for that class.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
交换
的正确使用。当您编写“库”代码并希望在swap
上启用 ADL(参数相关查找)时,可以这样编写。另外,这与 SFINAE 无关。swap
函数的正确方法:如果现在使用
swap
,如 1) 所示,您的函数将被找到。另外,如果您绝对需要,您可以将该函数设为友元,或者提供由自由函数调用的成员swap
:std::swap
专门用于模板类,因此您必须在命名空间中提供一个自由函数。如果我可以这么说的话,这并不是一件坏事。现在,显式专门化也是可能的,但通常您不想专门化函数模板:swap
. Write it this way when you write "library" code and want to enable ADL (argument-dependent lookup) onswap
. Also, this has nothing to do with SFINAE.swap
function for your class:If
swap
is now used as shown in 1), your function will be found. Also, you may make that function a friend if you absolutely need to, or provide a memberswap
that is called by the free function:std::swap
for template classes, you have to provide a free function in your namespace. Not a bad thing, if I may say so. Now, an explicit specialization is also possible, but generally you do not want to specialize a function template:似乎 (2)(在声明用户定义类的同一命名空间中独立的
交换
)是唯一允许提供交换
的方式 code> 对于用户定义的类,因为向命名空间std
添加声明通常是未定义的行为。 扩展命名空间 std (cppreference.com):,并且
swap
是未表示为这些例外之一。因此,将您自己的swap
重载添加到std
命名空间是一种未定义的行为。还据说标准库使用对
swap
函数的非限定调用,以便为用户类调用用户定义的swap
(如果此类用户定义的swap)提供了。
可交换 (cppreference.com):
交换 (www.cplusplus.com):
但请注意,直接对用户定义的类使用
std::swap
函数会调用std::swap
的通用版本,而不是用户定义的swap
:因此建议在用户代码中以与标准库中相同的方式调用
swap
函数:It seems that (2) (free standing
swap
in the same namespace where the user-defined class is declared) is the only allowed way to provideswap
for a user-defined class, because adding declarations to namespacestd
is generally an undefined behavior. Extending the namespace std (cppreference.com):And
swap
is not denoted as one of those exceptions. So adding your ownswap
overload to thestd
namespace is an undefined behavior.It's also said that the standard library uses an unqualified call to the
swap
function in order to call user-definedswap
for a user class if such user-definedswap
is provided.Swappable (cppreference.com):
swap (www.cplusplus.com):
But note that directly using the
std::swap
function for a user-defined class calls the generic version ofstd::swap
instead of the user-definedswap
:So it is recommended to call the
swap
function in user code in the same way as it is done in the standard library:要回答编辑,其中类可能是模板类,您根本不需要专门化。考虑这样一个类:
您可以定义这样的类:
如果您希望能够创建一个函数来实现所有 3 个交换(不是这个示例类保证它),您就像 Xeo 在 (2) 中所说的那样...无需专门化,只需创建一个常规模板函数:
交换模板函数应位于与您要交换的类相同的命名空间中。即使您没有使用 ADL 引用该命名空间,以下方法也将找到并使用该交换:
To answer the EDIT, where the classes may be template classes, you don't need specialization at all. consider a class like this:
you may define classes such as:
if you want to be able to create one function to implement all 3 swaps (not that this example class warrants it) you do just like Xeo said in (2)... without specialization but just make a regular template function:
The swap template function should be located in the same namespace as the class you're trying to swap. the following method will find and use that swap even though you're not referencing that namespace using ADL: