Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to provide a swap function for my class?

Tags:

c++

stl

swap

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.

like image 978
pic11 Avatar asked Jun 17 '11 02:06

pic11


1 Answers

  1. is the proper use of swap. Write it this way when you write "library" code and want to enable ADL (argument-dependent lookup) on swap. Also, this has nothing to do with SFINAE.
// some algorithm in your code template<class T> void foo(T& lhs, T& rhs) {     using std::swap; // enable 'std::swap' to be found                     // if no other 'swap' is found through ADL     // some code ...     swap(lhs, rhs); // unqualified call, uses ADL and finds a fitting 'swap'                     // or falls back on 'std::swap'     // more code ... } 
  1. Here is the proper way to provide a swap function for your class:
namespace Foo {  class Bar{}; // dummy  void swap(Bar& lhs, Bar& rhs) {     // ... }  } 

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 member swap that is called by the free function:

// version 1 class Bar{ public:     friend void swap(Bar& lhs, Bar& rhs) {     // ....     } };  // version 2 class Bar{ public:     void swap(Bar& other) {     // ...     } };  void swap(Bar& lhs, Bar& rhs) {     lhs.swap(rhs); }  ... 
  1. You mean an explicit specialization. Partial is still something else and also not possible for functions, only structs / classes. As such, since you can't specialize 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:
namespace std {  // only allowed to extend namespace std with specializations  template<> // specialization void swap<Bar>(Bar& lhs, Bar& rhs) noexcept {     // ... }  } 
  1. No, as 1) is distinct from 2) and 3). Also, having both 2) and 3) will lead to always having 2) picked, because it fits better.
like image 191
Xeo Avatar answered Oct 07 '22 07:10

Xeo