Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How would you apply an same operation to a set of independent variables in C++?

Edit Totally forgot to mention smth that's obvious to me:

a_func() wants to modify the var_xxx, so the solutions that iterate using a const type aren't completely satisfying (although they bring in ideas, for sure).

I feel the answer is simple yet can't find it.

Given:

A number (a small number, like 6, 8, 10) of variables of a user class type (precisely, a math vector object), where each variable has to have a unique name, defined by the algorithm (in order to be calculated and then used independently, and to be able to easily consult the paper that the code is based on)

Do:

In a piece of code, calculate and initialize those variables, referring to them by name; and then in another piece of code perform an operation on them in a sweep, without having to duplicate the code calling the operation (i.e. a function) for each and every variable.

Code goes like this:

// in a class declaration
vector_type var_abc, var_efg, var_xyz;

// in a class member function
// "some_math_xxx" pieces are coded inline, not as separate functions
var_abc = /* some_math_abc */;
var_efg = /* some_math_efg */ ;
var_xyz = /* some_math_xyz */ ;
a_func(var_abc); a_func(var_efg); a_func(var_xyz);

I mean, I can of course type a_func(var_xxx) six or more times. But it, well, feels just wrong to me.

Thought of:

  • a hash to store the names of those cars (bad for the math using them later I guess)
  • a std::array<> of pointers to the vars (bit clumsy but works)
  • this code that fails to compile:

    for (vector_type& vr : { var_abc, var_efg, var_xyz }) { a_func(vr); } (error: binding const vector_type to reference of type vector_type&)

How would you solve this? I'd prefer an elegant solution, of course. The standard better be just C++11, though C++14 is ok too if it enables a super cute solution to this problem.

P.S. The question entering form says "the title is subjective and the Q may be closed". I'm sure this is not an opinion-based Q, as I'm not asking to compare the solutions, but to suggest some.

like image 918
iksemyonov Avatar asked Apr 13 '16 12:04

iksemyonov


1 Answers

The issue seems to be that you were trying to initialise a reference with a const value copied to the implicit initializer_list. This container, like all others, cannot contain references. So, instead, you get const values, since initializer_list (currently? and probably forever) only offers const access to its members.

So... just use pointers to the elements. They're not to be feared. This seems simple:

for ( auto const it: /* std::initializer_list<VecType *> */ {&vecA, &vecB, &vecC} ) {
    doStuff(*it);
    // N.B. it is a *const, not a const *const!
}

You don't need to explicitly specify the initializer_list type, as long as you're not using elements of various polymorphic pointer types or that require conversion operators (in which case, you do).

Unless I'm missing something, others' suggestions of putting everything through an extra layer of std::reference_wrapper seems to be an unnecessary hoop to jump through, just to avoid pointers for some reason. Other solutions might invoke copies, which could lead to a lot of confusion.

I kinda wish C++ had a range-for style 'automatic dereference` for this case, but getting that implemented would probably cause all kinds of syntactic ambiguity, which wouldn't really be worth it when it's simple enough this way.

like image 110
underscore_d Avatar answered Oct 29 '22 01:10

underscore_d