Search code examples
c++c++11overload-resolutionexplicit-object-parameter

How to perfectly forward `*this` object inside member function


Is it possible to perfectly forward *this object inside member functions? If yes, then how can we do it? If no, then why not, and what alternatives do we have to achieve the same effect.

Please see the code snippet below to understand the question better.

class Experiment {
public:
  double i, j;
  Experiment(double p_i = 0, double p_j = 0) : i(p_i), j(p_j) {}

  double sum() { return i + j + someConstant(); }

  double someConstant() && { return 10; }

  double someConstant() & { return 100; }
};

int main() {
  Experiment E(3, 5);
  std::cout << std::move(E).sum() << "\n";  // prints: 108
  std::cout << E.sum() << "\n";             // prints: 108
}

This output seems expected if we consider that *this object inside the member function double sum() is always either an lvalue or xvalue (thus a glvalue) . Please confirm if this is true or not.

How can we perfectly forward *this object to the member function call someConstant() inside the double sum() member function?

I tried using std::forward as follows:

double sum() {
    return i + j + std::forward<decltype(*this)>(*this).someConstant();
}

But this did not have any effect, and double someConstant() & overload is the one always being called.


Solution

  • This is not possible in C++11 without overloading sum for & and && qualifiers. (In which case you can determine the value category from the qualifier of the particular overload.)

    *this is, just like the result of any indirection, a lvalue, and is also what an implicit member function call is called on.

    This will be fixed in C++23 via introduction of an explicit object parameter for which usual forwarding can be applied: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0847r7.html