Home > Back-end >  Chaining a list of member functions where one member function's call depends on if boolean is t
Chaining a list of member functions where one member function's call depends on if boolean is t

Time:04-18

We have a class that is defined with chained member functions, and it is intended to be called like this

    Tensor().setA(args)
    .setB(args)
    .setC(args)
    .setD(args)
    .build();

But sometimes (if flag == true), we call it with this

    Tensor().setA(args)
    .setB(args)
    .setC(args)
    .setD(args)
    .setE(args)
    .build();

So currently, I have

if (flag == true) {
  return Tensor().setA(args)
    .setB(args)
    .setC(args)
    .setD(args)
    .setE(args)
    .build();
} else {
  return Tensor().setA(args)
    .setB(args)
    .setC(args)
    .setD(args)
    .build();
}

which seems there's some unnecessary duplicate code and I'm looking for suggestions on how to remove the duplication.

One method I though to is

auto temp = Tensor().setA(args)
    .setB(args)
    .setC(args)
    .setD(args);
if (flag == true) {
    temp.setE(args)
}
return temp.build();

but I'm not totally sure this won't slow down the pre-existing implementation.

Is it possible to do something like this (I know this is not valid C but I'm trying to illustrate a point)

return temp = Tensor().setA(args)
    .setB(args)
    .setC(args)
    .setD(args);
    (flag == true ? .setE(args) : do nothing)
    .build();

Tensor here is the class name (apologies for omitting this really important detail)

CodePudding user response:

If you can add a do-nothing method to Tensor with the same signature as setE(), you can do something like this:

Tensor& (Tensor::*setEOrNoOp)(argTypes) = flag? &Tensor::setE : &Tensor::noOp;

(Tensor{}
    .setA(args)
    .setB(args)
    .setC(args)
    .setD(args)
    .*setEOrNoOp)(args)
    .build();

Online Demo

If altering Tensor is not an option, then you can use a wrapper function/lambda instead:

Tensor& doSetE(Tensor &t, argTypes args)
{
    return t.setE(args);
}

Tensor& doNoOp(Tensor &t, argTypes)
{
    return t;
}

Tensor& (*setEOrNoOp)(Tensor&, argTypes) = flag? &doSetE : &doNoOp;

setEOrNoOp(
    Tensor{}
    .setA(args)
    .setB(args)
    .setC(args)
    .setD(args)
    , args)
    .build();

Online Demo

CodePudding user response:

I think this is the cleanest way to the eyes.

Tensor t;
t.setA(args);
t.setB(args);
t.setC(args);
t.setD(args);
if (flag)
    t.setE(args);
return t.build();
  • Related