Следуя What is the copy and swap idiom и How to provide a swap function for my class, я попытался реализовать функцию подкачки, как в последнем принятом варианте ответа номер 2 (имеющем свободную функцию, которая вызывает функцию-член) вместо прямой дружественной свободной функции в первом звене.Внедрение свопа в икону копирования и свопинга
Однако следующий не компилирует
#include <iostream>
// Uncommenting the following two lines won't change the state of affairs
// class Bar;
// void swap(Bar &, Bar &);
class Bar {
public:
Bar(unsigned int bottles=0) : bottles(bottles) { enforce(); } // (1)
Bar(Bar const & b) : bottles(b.bottles) { enforce(); } // (1)
Bar & operator=(Bar const & b) {
// bottles = b.bottles;
// enforce();
// Copy and swap idiom (maybe overkill in this example)
Bar tmp(b); // but apart from resource management it allows (1)
// to enforce a constraint on the internal state
swap(*this, tmp); // Can't see the swap non-member function (2)
return *this;
}
void swap(Bar & that) {
using std::swap;
swap(bottles, that.bottles);
}
friend std::ostream & operator<<(std::ostream & out, Bar const & b) {
out << b.bottles << " bottles";
return out;
}
private:
unsigned int bottles;
void enforce() { bottles /=2; bottles *= 2; } // (1) -- Ensure the number of bottles is even
};
void swap(Bar & man, Bar & woman) { // (2)
man.swap(woman);
}
int main() {
Bar man (5);
Bar woman;
std::cout << "Before -> m: " << man << "/w: " << woman << std::endl;
swap(man, woman);
std::cout << "After -> m: " << man << "/w: " << woman << std::endl;
return 0;
}
Я знаю, что копия и своп идиома является излишеством здесь, но она также позволяет применять некоторые ограничения на внутреннее состояние через конструктор копирования (1) (Более конкретным примером могло бы быть поддержание доли в сокращенной форме). К сожалению, это не компилируется, потому что единственным кандидатом для (2), который видит компилятор, является функция члена bar :: swap. Я застрял с подходом друзей, не являющимся членами?
EDIT: перейдите по ссылке my answer below, чтобы узнать, что у меня получилось, благодаря всем ответам и комментариям по этому вопросу.
никоим образом не ваш код следовать [успешное решение] (http://stackoverflow.com/a/3279550/366904) в GMan-х ответ. –
Если вы правильно реализуете оператор nothrow move-assign и move-constructor, нет необходимости реализовывать swap. –
Внутри класса, почему бы просто не вызвать 'this-> swap (other)'? – Yakk