0

Lets say we have a class TestClass, which provide a move constructor and a move assignment operator.

class TestClass {
    int data;
public:
    TestClass() : data(0) {}
    TestClass(TestClass const & other) = delete;
    TestClass& operator=(TestClass const & other) = delete;
    TestClass(TestClass&& other) : data(other.data) {
    }
    TestClass& operator=(TestClass&& other)  {
        data = other.data;
        return *this;
    }
};

We want encapsulate it with a macro, such that user can call the macro to create an instance, such as

#define TESTCLASS() TestClass()

auto instance = TESTCLASS(); 

This works well, except that each time user must declare a instance variable to hold the instance. if the user write

TESTCLASS(); 

only a temporary instance will be created and died immediately.

In case of the user might forget to declare the instance variable, I would prefer that the macro with a temporary variable to hold the instance.

#define TESTCLASS_HOLDER() \
           TEMPORARY_HOLDER_IN(CONCAT(TEMP_, __LINE__))

#define CONCAT(A, B) CONCAT_IMPL__(A, B)
#define CONCAT_IMPL__(A, B) A ## B

#define  TEMPORARY_HOLDER_IN(tempoary)   auto tempoary = TestClass()

By this way, we can hold the instance to a temporary variable.

TESTCLASS_HOLDER();

However, as this variable is temporary, user can not refer to it. What we need is a macro like TESTCLASS_HOLDER(), but be able to std::move the instance if user declares some other variable.

NEW_TESTCLASS_HOLDER();  // let this works together with the next line if any.
auto mytestclass = NEW_TESTCLASS_HOLDER(); //kind of chain assignment?

The problem is how to write such a macro NEW_TESTCLASS_HOLDER()?

phy nju
  • 289
  • 2
  • 7
  • Cannot user use `TEMPORARY_HOLDER_IN(var)` ? – Jarod42 Dec 18 '17 at 10:59
  • 1
    I don't see the point of the macro BTW. – Jarod42 Dec 18 '17 at 11:00
  • B/C the macro will have some other variables or functions to pass in. I just did not show that part to complicate the problem, so `TEMPORARY_HOLDER_IN(var)` is not preferred. And also `auto mytestclass = NEW_TESTCLASS_HOLDER();` is quite naturally `C/C++` to declare variable. – phy nju Dec 18 '17 at 11:03
  • Main point is let the instance created by the macro have a extended life time beyond the macro itself. Whatever the user cares or does not care the temporary variable created by the macro, its lifetime span is promised. In some situations, the user might want to refer to this object for further manipulation, then the user can declare a variable together with the macro. `auto mytestclass = NEW_TESTCLASS_HOLDER();`, so it can be called as `mytestclass.someMethod();` if necessary. – phy nju Dec 18 '17 at 11:11
  • "...s quite naturally C/C++ to declare variable" ... not it is not. There is no language called C/C++. [C has `auto`](https://stackoverflow.com/questions/2192547/where-is-the-c-auto-keyword-used) but it has quite a different meaning from the `auto` in C++ – 463035818_is_not_an_ai Dec 18 '17 at 11:14
  • I mean `type variable = value` way. I do not know C has `auto` though. Thanks – phy nju Dec 18 '17 at 11:16
  • imho the question is completely unclear. It is not clear what is the benefit of having the macro when the user could call the constructor directly. Also "the user might forget to declare the instance variable".. not clear why you consider this as a problem. If the user wants to use the instance later on, how could he forget to declare it? – 463035818_is_not_an_ai Dec 18 '17 at 11:20
  • In rare cases, the user need further manipulate with the instance, say cancel the function to be executed, or so. Then it need a object reference to operate. Only at this situation user need declare a variable. Try to make life easier. – phy nju Dec 18 '17 at 11:27
  • In C++17, you have `[[nodiscard]]` attribute to avoid the wrong usage `TESTCLASS();`. – Jarod42 Dec 18 '17 at 11:39
  • TestClass is a ScopeGuid class, Various functions can be passed into the class and scheduled to execute in the dtor. That's why I want the temporary object has a lifespan to current scope, so that functions exec when getting out of current scope. Most time, the user does not need give a variable name to hold the instance, as the macro can provide a temporary holder. – phy nju Dec 18 '17 at 11:41
  • Other possibility: `template static decltype(auto) TestClass::Run(F&& f) { return f(TestClass()); }` – Jarod42 Dec 18 '17 at 11:42

0 Answers0