8

Take the following bit of code that uses boost::asio.

#include <boost/asio.hpp>

using boost::asio::ip::tcp;

class SocketTest
{

private:            

    boost::asio::io_service& mIOService;
    tcp::acceptor mAcceptor; // Comment this line

public:

    SocketTest(boost::asio::io_service& io_service)
        : mIOService(io_service)
        , mAcceptor(io_service, tcp::endpoint(tcp::v4(), 8080)) // Comment this line
    {      
    }
};

If you comment the two tagged lines the compiler (Visual Studio 2010) gives out the following warning when compiling on /W4.

warning C4512: 'SocketTest' : assignment operator could not be generated

What makes those two lines so special? Why does their existence allow the generation of the assignment operator?

Sam Miller
  • 23,808
  • 4
  • 67
  • 87
UberMongoose
  • 319
  • 3
  • 9

1 Answers1

7

The reason for this behaviour is that tcp::acceptor is not copyable (it inherits from basic_io_object, whose copy assignment operator is private, so its own copy assignment operator is not implicitly declared). Having a non-copyable member avoids the generation of the implicitly declared copy assignment operator, but does not raise a warning because this is considered the expected behaviour.

On the other hand, if you comment-out those two lines, your class is left with just a reference member; this also makes your class non-copyiable, but does raise a warning according to Visual Studio documentation. I agree that this is also expected, but the compiler implementers decided to give you a warning just in case. The reason may be that making a class explicitly non-copyable (such as is the case with basic_io_object) is an explicit design decision, but I am just guessing here.

Gorpik
  • 10,940
  • 4
  • 36
  • 56
  • Ah, yes. You seem to be correct. Inheriting from boost::noncopyable solved the warning. It also explains why my attempt at recreating the problem with an atomic type (int& and int) doesn't recreate the issue. Many thanks. – UberMongoose Dec 05 '12 at 09:47
  • Update from the future: in C++11 there's a better way to handle this: http://stackoverflow.com/questions/9458741/with-explicitly-deleted-member-functions-in-c11-is-it-still-worthwhile-to-inh – Tim Nov 11 '16 at 01:50