Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why would I want a .* operator in C++?

I recently found out that the .* operator (and the closely related ->* operator) exists in C++. (See this question.)

Seems neat at first, but why would I ever need such a thing? The two answers in the linked question provided contrived examples which would benefit from a direct function call.

Where a direct function call is inconvenient, a function object could be used instead, like the lambda functions that may be used in std::sort. This removes a level of indirection and hence would be more performant than using .*.

The linked question also mentioned a simplified version of this example:

struct A {
    int a;
    int b;
};

void set_member(A& obj, int A::* ptr, int val){
    obj.*ptr = val;
}

int main()
{
    A obj;
    set_member(obj, &A::b, 5);
    set_member(obj, &A::a, 7);
    // Both members of obj are now assigned
}

But it's pretty trivial (perhaps even better practice because it's cleaner and isn't unnecessarily constrained to members of A) to do this instead:

struct A {
    int a;
    int b;
};

void set_me(int& out, int val){
    out = val;
}

int main()
{
    A obj;
    set_me(obj.b, 5);
    set_me(obj.a, 7);
    // Both members of obj are now assigned
}

In conclusion, a pointer-to-member-function might be replaced by a function object, and a pointer-to-member-variable might be replaced by a direct reference of said variable or a function object. Doing so might also increase the efficiency of the code due to one less indirection.

This question only provides examples where my conclusion stands, so it does not answer my question.

Apart from interfacing legacy code which uses .* (in which there would be no choice at all), when, really, would I want to use .*?

like image 683
Bernard Avatar asked Jun 28 '17 03:06

Bernard


1 Answers

Your example is too trivial to be illustrative. Consider a bit more complicated one

struct A {
    int a;
    int b;
};

void set_n_members(A objs[], unsigned n, int A::* ptr, int val)
{
  for (unsigned i = 0; i < n; ++i)
     objs[i].*ptr = val;
}

int main()
{
    A objs[100];
    set_n_members(objs, 100, &A::b, 5);
    set_n_members(objs, 100, &A::a, 7);
}

How would you rewrite this without int A::* ptr and without inducing code bloat?

like image 62
AnT Avatar answered Nov 09 '22 23:11

AnT