Search code examples
c++c++11templatesreferenceauto

A good way to organize a code involving const references with limited scope and templates in C++


So, I have the following piece of code:

if (some_boolean_statement)
{
    const auto& ref = getRef<TYPE_A>(); //getRef returns TYPE_A
    doStuff(ref);
}
else
{
    const auto& ref = getRef<TYPE_B>(); //getRef returns TYPE_B
    doStuff(ref);
}

So, I want to obtain a constant reference ref which depending on some_boolean_statement being true or false is either of TYPE_A or TYPE_B. After that, no matter what, I will call an overloaded function doStuff() that can accept both types as an input.

Notes:

  • getRef<TYPE_A>() and getRef<TYPE_B>() are operating on different data and are pretty much unrelated
  • some_boolean_statement is run-time

Now, I don't like that I have to write doStuff(ref); in both branches of the if statement. But since the scope of ref is limited, I don't see a clear way to do it.

Am I missing something really simple? Any advice?


Solution

  • Invert control flow and a runtime to compile time dispatcher.

    This is insanely complex in , and modestly complex in .

    In you can get:

    pick( some_boolean_statement,
      &getRef<TYPE_A>,
      &getRef<TYPE_B>
    )([&](auto* getRef){
      const auto& ref = getRef();
      doStuff(ref);
    });
    

    but basically every step along that way is a pain in .

    Another approach would be to make a std () or boost () variant that stores a pointer to TYPE_A or TYPE_B. Then use visit; but even here, you'd need an auto lambda to keep your code short.

    The simplest version is:

    auto doWork = [&](const auto& ref) {
      doStuff(ref);
    };
    if (some_boolean_statement) {
      doWork(getRef<TYPE_A>());
    } else {
      doWork(getRef<TYPE_B>());
    }