Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are there so many specializations of std::swap?

While looking at the documentation for std::swap, I see a lot of specializations.
It looks like every STL container, as well as many other std facilities have a specialized swap.
I thought with the aid of templates, we wouldn't need all of these specializations?

For example,
If I write my own pair it works correctly with the templated version:

template<class T1,class T2>  struct my_pair{     T1 t1;     T2 t2; };  int main() {     my_pair<int,char> x{1,'a'};     my_pair<int,char> y{2,'b'};     std::swap(x,y); }  

So what it is gained from specializing std::pair?

template< class T1, class T2 > void swap( pair<T1,T2>& lhs, pair<T1,T2>& rhs ); 

I'm also left wondering if I should be writing my own specializations for custom classes,
or simply relying on the template version.

like image 797
Trevor Hickey Avatar asked Feb 01 '17 16:02

Trevor Hickey


People also ask

What does std :: swap do?

The function std::swap() is a built-in function in the C++ Standard Template Library (STL) which swaps the value of two variables. Parameters: The function accepts two mandatory parameters a and b which are to be swapped. The parameters can be of any data type.

Does STD swap use move semantics?

Is specializing std::swap deprecated now that we have move semantics? No. This is the generic version, but you can optimize it to skip a third move operation.

Is STD swap Atomic?

It is not atomic. Atomic operations are not cheap and 99% of the time you do not need the atomicity. There are (IIRC) some other means to get atomic operations but std::swap() is not one of them.

What header is swap in C++?

To use the swap() function, we need to include the header file <utility> in our C++ program.


2 Answers

So what it is gained from specializing std::pair?

Performance. The generic swap is usually good enough (since C++11), but rarely optimal (for std::pair, and for most other data structures).

I'm also left wondering if I should be writing my own specializations for custom classes, or simply relying on the template version.

I suggest relying on the template by default, but if profiling shows it to be a bottleneck, know that there is probably room for improvement. Premature optimization and all that...

like image 172
eerorika Avatar answered Sep 17 '22 14:09

eerorika


std::swap is implemented along the lines of the code below:

template<typename T> void swap(T& t1, T& t2) {     T temp = std::move(t1);      t1 = std::move(t2);     t2 = std::move(temp); } 

(See "How does the standard library implement std::swap?" for more information.)

So what it is gained from specializing std::pair?

std::swap can be specialized in the following way (simplified from libc++):

void swap(pair& p) noexcept(is_nothrow_swappable<first_type>{} &&                             is_nothrow_swappable<second_type>{}) {     using std::swap;     swap(first,  p.first);     swap(second, p.second); } 

As you can see, swap is directly invoked on the elements of the pair using ADL: this allows customized and potentially faster implementations of swap to be used on first and second (those implementations can exploit the knowledge of the internal structure of the elements for more performance).

(See "How does using std::swap enable ADL?" for more information.)

like image 24
Vittorio Romeo Avatar answered Sep 18 '22 14:09

Vittorio Romeo