Just had a chance to try this and the code written your way works fine, but I can't figure out how to put the socket into a class, everything I've tried either fails at Noncopyable or I get an error about the private member function std::unique_ptr<_Ty>.
If the socket is a member of a class, the class itself will become noncopyable. As long as you don't invoke copy constructor or copy assignment operator, this is not a problem.
Edit: I kind of fixed it. I don't know if this makes any sense, but here's what I did:
The question is how your ownership semantics look. Also make sure you consider the
rule of three, i.e. also declare copy assignment operator when you need copy semantics. But I think in your case, you don't want to copy the client, but move it to the container. For this, you need C++11 move semantics.
Enabling move semantics requires you to define some special member functions, move constructor and move assignment operator. Actually, a fully C++11 conforming compiler can generate them on its own, if you define none of them (see
rule of five). Nevertheless I'll show you how to do it manually, it doesn't hurt to know the syntax:
class Client
{
public:
// Default constructor
Client()
: socket(new sf::TcpSocket)
{
}
// Move constructor
Client(Client&& source)
: socket(std::move(source.socket))
{
}
// Move assignment operator
Client& operator= (Client&& source)
{
socket = std::move(source.socket);
return *this;
}
// No destructor necessary
private:
std::unique_ptr<sf::TcpSocket> socket;
}
These may be new C++ features for you. The
&& denotes a rvalue reference, it can bind any rvalues (that is, temporary objects and results of
std::move()). std::move() itself is only required to convert a named object (lvalue) to a rvalue, in order to bind a rvalue reference to it.
socket = std::move(std::unique_ptr<sf::TcpSocket> (new sf::TcpSocket));
You never need to invoke
std::move() on unnamed temporary objects, since they are already rvalues. Instead, the equivalent code would be:
socket.reset(new sf::TcpSocket);
I recommend to read about C++11 move semantics. There was a good article series called C++Next, but it appears to be offline at the moment. Try the
web archive.
By the way, your code is very convoluted, you should clean it up. Concerning removal of elements, don't do it while iterating (or at least consider the return value of
erase()). Have a look at
std::remove_if(). And don't use
printf() when you want to output
std::string objects, after all C++ provides
std::cout.