0

I have the following function:

void scan(DataRow& input) {
    if(input.isRaw()) {
        ...
    }
    if(input.isExternal()) {
        ...
    }
    if(input.hasMultipleFields()) {
        ...
        for(auto& field: input.fields()) {
            if(field.size() == 2) {
                ...
            }
        }
    }

}

The DataRow class has many sub-classes and all the is functions above are virtual.

This function is used to scan several large groups of data rows. For each group, all data row instances will have the same property (e.g., all raw, all external).

So instead of having all these if/else logics in the scan function, I am thinking if there is a way to generate ad-hoc code. For example, now I already know my next group are all raw (or all not), then I can get rid of the first if branch.

In Java, I used to do such kind of things by generating byte code for class and dynamically load the generated class in JVM. I know the same trick does not work for C++ but I have little experience how to do this. Can anyone give some hint? Thanks!

5
  • Try templates with overloaded methods. Commented Jun 6, 2020 at 7:05
  • I'm not sure if this is what you need, but try having a look at compile-time if statements i.e. if constexpr() Commented Jun 6, 2020 at 7:10
  • @VarunNayak Thanks but constexpr is a compile-time evaluation. What I need is runtime-evaluation. Commented Jun 6, 2020 at 7:11
  • @Hack06 can you please be more specific? Commented Jun 6, 2020 at 7:12
  • I meant if you're talking about dynamic code generation, then templates are the way to go. And overloads are the way to let the compiler connect your code-logic without if/else constructs. Also, there are variadic templates since C++11 that give you more freedom to tweak around your templates. Another mechanics to tweak your code generation/compilation is preprocessor directives, but those should not be considered on the first place. Commented Jun 6, 2020 at 9:07

1 Answer 1

2

You cannot easily manipulate executable code during runtime. But your question doesn’t look like you’d have to go down that road anway.

You have groups of rows with similar properties and special processing logic for each group. Also, there seems to be a small fixed number of different kinds of groups.

You have all necessary information to split up your code at compile time – “programming time” actually. Split the scan() function into one function for each kind of group and call scan_raw(), scan_external(), etc. accordingly.

This reduces the number of if condition checks from once per row to once per group. As an added benefit the separate scan functions can use the appropriate derived class as their parameter type and you can get rid of the whole isSomething() machinery.

Hm, at this point I’m tempted to point you towards std::variant and std::visit (or their Boost equivalents). That could be a larger refactoring, though. Because when using them you’d ideally use them as a complete replacement for your current inheritance based polymorphism approach.

Sign up to request clarification or add additional context in comments.

2 Comments

I think such a simple solution won't work for OP, but we will never know why.
I end up using a similar method. I separate the processing into many functors, and based on the condition choose the functors to be applied. I put all these functors in a vector and apply them one by one to the given input.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.