2

Is there any way to create a generic macro to delete copy ctor, assignment operator

    //Below two lines are class specific, and looking to replace with some generic way
    //without mentioning hardcoded class name
    #define NO_COPY             Original(_In_ const Original&) = delete;
    #define NO_ASSIGNMENT       Original& operator=(_In_ const Original&) = delete;
    
    //simple class
    class Original
    {
    public:
        NO_COPY;
        NO_ASSIGNMENT;
    };
Mayur
  • 2,583
  • 16
  • 28
  • 1
    are you looking for `boost::noncopyable` ? Does it have to be a macro? – 463035818_is_not_an_ai Jun 21 '21 at 17:42
  • does c++ has similar something? – Mayur Jun 21 '21 at 17:43
  • 2
    Why do you need that? `Original(const Original& ) = delete;` is only several characters more and leaves nothing to imagination (unlike a macro which people would need to check in order to figure out what is going on) There is a good reason to avoid macros unless unavoidable, and this use-case doesn't seem like the unavoidable one. – SergeyA Jun 21 '21 at 17:44
  • I am just exploring this stuff if its available but I feel for larger code bases, one simple macro seems clean and uniform – Mayur Jun 21 '21 at 17:45
  • Did you look at this? https://stackoverflow.com/questions/10531497/template-in-a-macros-in-c. The obvious problem is this technique becomes a real bear to read. – Matt Jun 21 '21 at 17:46
  • Well, the answer is it is not possible. In order to implement such macro, you need to have class name available to you in a macro context, and there is no way to get it. – SergeyA Jun 21 '21 at 17:49
  • "one simple macro seems clean and uniform" this is how it starts. Next day you add another one, because one more isnt too bad. Already a single macro pollutes your complete code base. Nowadays the good uses cases for macros are extremely rare – 463035818_is_not_an_ai Jun 21 '21 at 17:50

1 Answers1

6

boost::noncopyable is this:

  class noncopyable
  {
  protected:
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && !defined(BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS)
      BOOST_CONSTEXPR noncopyable() = default;
      ~noncopyable() = default;
#else
      noncopyable() {}
      ~noncopyable() {}
#endif
#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
      noncopyable( const noncopyable& ) = delete;
      noncopyable& operator=( const noncopyable& ) = delete;
#else
  private:  // emphasize the following members are private
      noncopyable( const noncopyable& );
      noncopyable& operator=( const noncopyable& );
#endif
  };

Usage is

struct X : private boost::noncopyable {};

If you do not want boost, it is straightforward to write your own my::noncopyable. The protected constructor and destructor are merely to make clear that the class is meant to be used as base class. Without the pre-C++11 conditions, the class is just:

  class noncopyable
  {
  protected:
      constexpr noncopyable() = default;
      ~noncopyable() = default;
      noncopyable( const noncopyable& ) = delete;
      noncopyable& operator=( const noncopyable& ) = delete;
  };

The macro you are asking for does not exist. As Sergey pointed out in a comment, you would at least have to pass the name of the class to the macro, which makes the point of typing less moot.

Last but not least, I suggest you to read this answer which makes some good points against a noncopyable base class and for spelling out the deleted member functions. Don't try to be too lazy. Less typing is not always the way to cleaner code.

HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207
463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185