How to avoid run-time checks for running parts of code that become unreachable after compilation?How can I profile C++ code running on Linux?Counting the total of same running processes in C++Usage of this next_combination codeIdentify objects in boost::shared_ptr<boost::thread>How C++ reference worksNamespaces and the Pre-Processorstd::atomic_is_lock_free(shared_ptr<T>*) didn't compileCleaning data after exception on class constructorTwo-level bind fails on GCC/libstdc++ and Clang/libc++How do i read bool value using std::istream

When handwriting 黄 (huáng; yellow) is it incorrect to have a disconnected 草 (cǎo; grass) radical on top?

How seriously should I take size and weight limits of hand luggage?

Pact of Blade Warlock with Dancing Blade

My ex-girlfriend uses my Apple ID to login to her iPad, do I have to give her my Apple ID password to reset it?

Why do I get negative height?

Does the feature within Tides of Chaos bypass the limitation of 1/day?

Avoiding the "not like other girls" trope?

How could indestructible materials be used in power generation?

Obtaining database information and values in extended properties

How obscure is the use of 令 in 令和?

Why is the sentence "Das ist eine Nase" correct?

Why was Sir Cadogan fired?

OP Amp not amplifying audio signal

How do I exit BASH while loop using modulus operator?

What exactly is ineptocracy?

How to coordinate airplane tickets?

Unlock My Phone! February 2018

Am I breaking OOP practice with this architecture?

How can I prove that a state of equilibrium is unstable?

What is a Samsaran Word™?

Rotate ASCII Art by 45 Degrees

Why is it a bad idea to hire a hitman to eliminate most corrupt politicians?

Why was the shrink from 8″ made only to 5.25″ and not smaller (4″ or less)

Do Iron Man suits sport waste management systems?



How to avoid run-time checks for running parts of code that become unreachable after compilation?


How can I profile C++ code running on Linux?Counting the total of same running processes in C++Usage of this next_combination codeIdentify objects in boost::shared_ptr<boost::thread>How C++ reference worksNamespaces and the Pre-Processorstd::atomic_is_lock_free(shared_ptr<T>*) didn't compileCleaning data after exception on class constructorTwo-level bind fails on GCC/libstdc++ and Clang/libc++How do i read bool value using std::istream













7















My program gets a couple of Boolean variables from the user, and their values won't change afterwards. Each Boolean variable enables a part of code. Something like this:



#include <iostream>

void callback_function(bool task_1, bool task_2, bool task_3)
if (task_1)
std::cout << "Running task 1" << std::endl;

if (task_2)
std::cout << "Running task 2" << std::endl;

if (task_3)
std::cout << "Running task 3" << std::endl;



int main()
bool task_1 = true;
bool task_2 = false;
bool task_3 = true;

while (true)
callback_function(task_1, task_2, task_3);


return 0;



Now my question is, since the Boolean variables are fixed every time the program calls callback_function(), is there a way to avoid the if statements inside the callback function?



This is one way to avoid the run-time checks (implement a callback function for all permutations of the Boolean variables --- only two cases are shown below):



#include <functional>
#include <iostream>

void callback_function_for_tasks_1_2_3()
std::cout << "Running task 1" << std::endl;
std::cout << "Running task 2" << std::endl;
std::cout << "Running task 3" << std::endl;


void callback_function_for_tasks_1_3()
std::cout << "Running task 1" << std::endl;
std::cout << "Running task 3" << std::endl;


int main()
bool task_1 = true;
bool task_2 = false;
bool task_3 = true;

std::function<void()> callback_function;
if (task_1 && task_2 && task_3)
callback_function = callback_function_for_tasks_1_2_3;
else if (task_1 && !task_2 && task_3)
callback_function = callback_function_for_tasks_1_3;


while (true)
callback_function();


return 0;



The problem is I have to implement 2^n different callback functions, if there are n Boolean variables. Is there a better way to accomplish this?










share|improve this question







New contributor




Alireza Shafaei is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.















  • 6





    If you’re interested in performance, don’t use std::function when a function pointer will do.

    – Davis Herring
    2 days ago






  • 5





    Have you actually measured whether these conditional statements make a difference? This looks like a pretty pointless optimization effort to me. Or, if you're trying to solve an actual problem with this, it may be the wrong approach, a so-called "XY problem". Please, as a new user, also take the tour and read How to Ask.

    – Ulrich Eckhardt
    2 days ago











  • If you go with with the 2nd approach, I believe, you will end up doing more checks then the 1st approch. Because each compound checks you are doing in the 2nd one will computationally cost you more than the 1st. I am not sure what are you trying to accomplish here, but if your concern is that for a false flag, the statements inside the block will take time to execute, then you don't have to worry about that. Because if the flag is false, the block will not take any execution time. And checking 1 by 1 will be cheaper than the combinations.

    – ABM Ruman
    2 days ago







  • 2





    @ABMRuman He'd be doing more checks only once, not every time in the loop. If this is a long running application... One could safe quite a lot of checks if one combined the conditions inside an unsigned int/uint32_t/uint64_t (depending on number of checks) and select the function via a switch statement. The functions might be generated via a template function using if constexpr inside, so one wouldn't need to write all the functions explicitly.

    – Aconcagua
    2 days ago











  • Joining @UlrichEckhardt: You should first run a profiler to find the hottest spots to optimise. Optimising the called functions at the right places will most likely bring you much more performance gain than avoiding these view ifs...

    – Aconcagua
    2 days ago















7















My program gets a couple of Boolean variables from the user, and their values won't change afterwards. Each Boolean variable enables a part of code. Something like this:



#include <iostream>

void callback_function(bool task_1, bool task_2, bool task_3)
if (task_1)
std::cout << "Running task 1" << std::endl;

if (task_2)
std::cout << "Running task 2" << std::endl;

if (task_3)
std::cout << "Running task 3" << std::endl;



int main()
bool task_1 = true;
bool task_2 = false;
bool task_3 = true;

while (true)
callback_function(task_1, task_2, task_3);


return 0;



Now my question is, since the Boolean variables are fixed every time the program calls callback_function(), is there a way to avoid the if statements inside the callback function?



This is one way to avoid the run-time checks (implement a callback function for all permutations of the Boolean variables --- only two cases are shown below):



#include <functional>
#include <iostream>

void callback_function_for_tasks_1_2_3()
std::cout << "Running task 1" << std::endl;
std::cout << "Running task 2" << std::endl;
std::cout << "Running task 3" << std::endl;


void callback_function_for_tasks_1_3()
std::cout << "Running task 1" << std::endl;
std::cout << "Running task 3" << std::endl;


int main()
bool task_1 = true;
bool task_2 = false;
bool task_3 = true;

std::function<void()> callback_function;
if (task_1 && task_2 && task_3)
callback_function = callback_function_for_tasks_1_2_3;
else if (task_1 && !task_2 && task_3)
callback_function = callback_function_for_tasks_1_3;


while (true)
callback_function();


return 0;



The problem is I have to implement 2^n different callback functions, if there are n Boolean variables. Is there a better way to accomplish this?










share|improve this question







New contributor




Alireza Shafaei is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.















  • 6





    If you’re interested in performance, don’t use std::function when a function pointer will do.

    – Davis Herring
    2 days ago






  • 5





    Have you actually measured whether these conditional statements make a difference? This looks like a pretty pointless optimization effort to me. Or, if you're trying to solve an actual problem with this, it may be the wrong approach, a so-called "XY problem". Please, as a new user, also take the tour and read How to Ask.

    – Ulrich Eckhardt
    2 days ago











  • If you go with with the 2nd approach, I believe, you will end up doing more checks then the 1st approch. Because each compound checks you are doing in the 2nd one will computationally cost you more than the 1st. I am not sure what are you trying to accomplish here, but if your concern is that for a false flag, the statements inside the block will take time to execute, then you don't have to worry about that. Because if the flag is false, the block will not take any execution time. And checking 1 by 1 will be cheaper than the combinations.

    – ABM Ruman
    2 days ago







  • 2





    @ABMRuman He'd be doing more checks only once, not every time in the loop. If this is a long running application... One could safe quite a lot of checks if one combined the conditions inside an unsigned int/uint32_t/uint64_t (depending on number of checks) and select the function via a switch statement. The functions might be generated via a template function using if constexpr inside, so one wouldn't need to write all the functions explicitly.

    – Aconcagua
    2 days ago











  • Joining @UlrichEckhardt: You should first run a profiler to find the hottest spots to optimise. Optimising the called functions at the right places will most likely bring you much more performance gain than avoiding these view ifs...

    – Aconcagua
    2 days ago













7












7








7


1






My program gets a couple of Boolean variables from the user, and their values won't change afterwards. Each Boolean variable enables a part of code. Something like this:



#include <iostream>

void callback_function(bool task_1, bool task_2, bool task_3)
if (task_1)
std::cout << "Running task 1" << std::endl;

if (task_2)
std::cout << "Running task 2" << std::endl;

if (task_3)
std::cout << "Running task 3" << std::endl;



int main()
bool task_1 = true;
bool task_2 = false;
bool task_3 = true;

while (true)
callback_function(task_1, task_2, task_3);


return 0;



Now my question is, since the Boolean variables are fixed every time the program calls callback_function(), is there a way to avoid the if statements inside the callback function?



This is one way to avoid the run-time checks (implement a callback function for all permutations of the Boolean variables --- only two cases are shown below):



#include <functional>
#include <iostream>

void callback_function_for_tasks_1_2_3()
std::cout << "Running task 1" << std::endl;
std::cout << "Running task 2" << std::endl;
std::cout << "Running task 3" << std::endl;


void callback_function_for_tasks_1_3()
std::cout << "Running task 1" << std::endl;
std::cout << "Running task 3" << std::endl;


int main()
bool task_1 = true;
bool task_2 = false;
bool task_3 = true;

std::function<void()> callback_function;
if (task_1 && task_2 && task_3)
callback_function = callback_function_for_tasks_1_2_3;
else if (task_1 && !task_2 && task_3)
callback_function = callback_function_for_tasks_1_3;


while (true)
callback_function();


return 0;



The problem is I have to implement 2^n different callback functions, if there are n Boolean variables. Is there a better way to accomplish this?










share|improve this question







New contributor




Alireza Shafaei is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.












My program gets a couple of Boolean variables from the user, and their values won't change afterwards. Each Boolean variable enables a part of code. Something like this:



#include <iostream>

void callback_function(bool task_1, bool task_2, bool task_3)
if (task_1)
std::cout << "Running task 1" << std::endl;

if (task_2)
std::cout << "Running task 2" << std::endl;

if (task_3)
std::cout << "Running task 3" << std::endl;



int main()
bool task_1 = true;
bool task_2 = false;
bool task_3 = true;

while (true)
callback_function(task_1, task_2, task_3);


return 0;



Now my question is, since the Boolean variables are fixed every time the program calls callback_function(), is there a way to avoid the if statements inside the callback function?



This is one way to avoid the run-time checks (implement a callback function for all permutations of the Boolean variables --- only two cases are shown below):



#include <functional>
#include <iostream>

void callback_function_for_tasks_1_2_3()
std::cout << "Running task 1" << std::endl;
std::cout << "Running task 2" << std::endl;
std::cout << "Running task 3" << std::endl;


void callback_function_for_tasks_1_3()
std::cout << "Running task 1" << std::endl;
std::cout << "Running task 3" << std::endl;


int main()
bool task_1 = true;
bool task_2 = false;
bool task_3 = true;

std::function<void()> callback_function;
if (task_1 && task_2 && task_3)
callback_function = callback_function_for_tasks_1_2_3;
else if (task_1 && !task_2 && task_3)
callback_function = callback_function_for_tasks_1_3;


while (true)
callback_function();


return 0;



The problem is I have to implement 2^n different callback functions, if there are n Boolean variables. Is there a better way to accomplish this?







c++






share|improve this question







New contributor




Alireza Shafaei is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question







New contributor




Alireza Shafaei is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question






New contributor




Alireza Shafaei is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 2 days ago









Alireza ShafaeiAlireza Shafaei

362




362




New contributor




Alireza Shafaei is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





Alireza Shafaei is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






Alireza Shafaei is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







  • 6





    If you’re interested in performance, don’t use std::function when a function pointer will do.

    – Davis Herring
    2 days ago






  • 5





    Have you actually measured whether these conditional statements make a difference? This looks like a pretty pointless optimization effort to me. Or, if you're trying to solve an actual problem with this, it may be the wrong approach, a so-called "XY problem". Please, as a new user, also take the tour and read How to Ask.

    – Ulrich Eckhardt
    2 days ago











  • If you go with with the 2nd approach, I believe, you will end up doing more checks then the 1st approch. Because each compound checks you are doing in the 2nd one will computationally cost you more than the 1st. I am not sure what are you trying to accomplish here, but if your concern is that for a false flag, the statements inside the block will take time to execute, then you don't have to worry about that. Because if the flag is false, the block will not take any execution time. And checking 1 by 1 will be cheaper than the combinations.

    – ABM Ruman
    2 days ago







  • 2





    @ABMRuman He'd be doing more checks only once, not every time in the loop. If this is a long running application... One could safe quite a lot of checks if one combined the conditions inside an unsigned int/uint32_t/uint64_t (depending on number of checks) and select the function via a switch statement. The functions might be generated via a template function using if constexpr inside, so one wouldn't need to write all the functions explicitly.

    – Aconcagua
    2 days ago











  • Joining @UlrichEckhardt: You should first run a profiler to find the hottest spots to optimise. Optimising the called functions at the right places will most likely bring you much more performance gain than avoiding these view ifs...

    – Aconcagua
    2 days ago












  • 6





    If you’re interested in performance, don’t use std::function when a function pointer will do.

    – Davis Herring
    2 days ago






  • 5





    Have you actually measured whether these conditional statements make a difference? This looks like a pretty pointless optimization effort to me. Or, if you're trying to solve an actual problem with this, it may be the wrong approach, a so-called "XY problem". Please, as a new user, also take the tour and read How to Ask.

    – Ulrich Eckhardt
    2 days ago











  • If you go with with the 2nd approach, I believe, you will end up doing more checks then the 1st approch. Because each compound checks you are doing in the 2nd one will computationally cost you more than the 1st. I am not sure what are you trying to accomplish here, but if your concern is that for a false flag, the statements inside the block will take time to execute, then you don't have to worry about that. Because if the flag is false, the block will not take any execution time. And checking 1 by 1 will be cheaper than the combinations.

    – ABM Ruman
    2 days ago







  • 2





    @ABMRuman He'd be doing more checks only once, not every time in the loop. If this is a long running application... One could safe quite a lot of checks if one combined the conditions inside an unsigned int/uint32_t/uint64_t (depending on number of checks) and select the function via a switch statement. The functions might be generated via a template function using if constexpr inside, so one wouldn't need to write all the functions explicitly.

    – Aconcagua
    2 days ago











  • Joining @UlrichEckhardt: You should first run a profiler to find the hottest spots to optimise. Optimising the called functions at the right places will most likely bring you much more performance gain than avoiding these view ifs...

    – Aconcagua
    2 days ago







6




6





If you’re interested in performance, don’t use std::function when a function pointer will do.

– Davis Herring
2 days ago





If you’re interested in performance, don’t use std::function when a function pointer will do.

– Davis Herring
2 days ago




5




5





Have you actually measured whether these conditional statements make a difference? This looks like a pretty pointless optimization effort to me. Or, if you're trying to solve an actual problem with this, it may be the wrong approach, a so-called "XY problem". Please, as a new user, also take the tour and read How to Ask.

– Ulrich Eckhardt
2 days ago





Have you actually measured whether these conditional statements make a difference? This looks like a pretty pointless optimization effort to me. Or, if you're trying to solve an actual problem with this, it may be the wrong approach, a so-called "XY problem". Please, as a new user, also take the tour and read How to Ask.

– Ulrich Eckhardt
2 days ago













If you go with with the 2nd approach, I believe, you will end up doing more checks then the 1st approch. Because each compound checks you are doing in the 2nd one will computationally cost you more than the 1st. I am not sure what are you trying to accomplish here, but if your concern is that for a false flag, the statements inside the block will take time to execute, then you don't have to worry about that. Because if the flag is false, the block will not take any execution time. And checking 1 by 1 will be cheaper than the combinations.

– ABM Ruman
2 days ago






If you go with with the 2nd approach, I believe, you will end up doing more checks then the 1st approch. Because each compound checks you are doing in the 2nd one will computationally cost you more than the 1st. I am not sure what are you trying to accomplish here, but if your concern is that for a false flag, the statements inside the block will take time to execute, then you don't have to worry about that. Because if the flag is false, the block will not take any execution time. And checking 1 by 1 will be cheaper than the combinations.

– ABM Ruman
2 days ago





2




2





@ABMRuman He'd be doing more checks only once, not every time in the loop. If this is a long running application... One could safe quite a lot of checks if one combined the conditions inside an unsigned int/uint32_t/uint64_t (depending on number of checks) and select the function via a switch statement. The functions might be generated via a template function using if constexpr inside, so one wouldn't need to write all the functions explicitly.

– Aconcagua
2 days ago





@ABMRuman He'd be doing more checks only once, not every time in the loop. If this is a long running application... One could safe quite a lot of checks if one combined the conditions inside an unsigned int/uint32_t/uint64_t (depending on number of checks) and select the function via a switch statement. The functions might be generated via a template function using if constexpr inside, so one wouldn't need to write all the functions explicitly.

– Aconcagua
2 days ago













Joining @UlrichEckhardt: You should first run a profiler to find the hottest spots to optimise. Optimising the called functions at the right places will most likely bring you much more performance gain than avoiding these view ifs...

– Aconcagua
2 days ago





Joining @UlrichEckhardt: You should first run a profiler to find the hottest spots to optimise. Optimising the called functions at the right places will most likely bring you much more performance gain than avoiding these view ifs...

– Aconcagua
2 days ago












3 Answers
3






active

oldest

votes


















15














Ensuring that if statements are evaluated at compile time



C++17 introduces if constexpr, which does exactly this:



template<bool task_1, bool task_2, bool task_3>
void callback_function()
if constexpr (task_1)
std::cout << "Running task 1" << std::endl;

if constexpr (task_2)
std::cout << "Running task 2" << std::endl;

if constexpr (task_3)
std::cout << "Running task 3" << std::endl;




If you have optimizations enabled, if constexpr isn't necessary. Even if you use a regular if instead of if constexpr, because the bools are now templated, the compiler will be able to eliminate the if statements entirely, and just run the tasks. If you look at the assembly produced here, you'll see that even at -O1, there are no if statements in any of the callback functions.



We can now use callback_function directly as a function pointer, avoiding function<void()>:



int main() 
using callback_t = void(*)();
callback_t func = callback_function<true, false, true>;

// Do stuff with func



We can also name the bools by assigning them to constexpr variables:



int main() 
using callback_t = void(*)();
constexpr bool do_task1 = true;
constexpr bool do_task2 = false;
constexpr bool do_task3 = true;
callback_t func = callback_function<do_task1, do_task2, do_task3>;

// Do stuff with func



Automatically creating a lookup table of all possible callback functions



You mentioned choosing between different callback functions at runtime. We can do this pretty easily with a lookup table, and we can use templates to automatically create a lookup table of all possible callback functions.



The first step is to get a callback function from a particular index:



// void(*)() is ugly to type, so I alias it
using callback_t = void(*)();

// Unpacks the bits
template<size_t index>
constexpr auto getCallbackFromIndex() -> callback_t

constexpr bool do_task1 = (index & 4) != 0;
constexpr bool do_task2 = (index & 2) != 0;
constexpr bool do_task3 = (index & 1) != 0;
return callback_function<do_task1, do_task2, do_task3>;



Once we can do that, we can write a function to create a lookup table from a bunch of indexes. Our lookup table will just be a std::array.



// Create a std::array based on a list of flags
// See https://en.cppreference.com/w/cpp/utility/integer_sequence
// For more information
template<size_t... Indexes>
constexpr auto getVersionLookup(std::index_sequence<Indexes...>)
-> std::array<callback_t, sizeof...(Indexes)>

return getCallbackFromIndex<Indexes>()...;


// Makes a lookup table containing all 8 possible callback functions
constexpr auto callbackLookupTable =
getVersionLookup(std::make_index_sequence<8>());


Here, callbackLookupTable contains all 8 possible callback functions, where callbackLookupTable[i] expands the bits of i to get the callback. For example, if i == 6, then i's bits are 110 in binary, so



callbackLookupTable[6] is callback_function<true, true, false>



Using the lookup table at runtime



Using the lookup table is really simple. We can get an index from a bunch of bools by bitshifting:



callback_t getCallbackBasedOnTasks(bool task1, bool task2, bool task3) 
// Get the index based on bit shifting
int index = ((int)task1 << 2) + ((int)task2 << 1) + ((int)task3);
// return the correct callback
return callbackLookupTable[index];



Example demonstrating how to read in tasks



We can get the bools at runtime now, and just call getCallbackBasedOnTasks to get the correct callback



int main() 
bool t1, t2, t3;
// Read in bools
std::cin >> t1 >> t2 >> t3;
// Get the callback
callback_t func = getCallbackBasedOnTasks(t1, t2, t3);
// Invoke the callback
func();






share|improve this answer

























  • The constexpr is IMHO a red herring, the important part is the use of template parameters which are evaluated at compile time. Any halfway-decent compiler is able to figure this out even without these consexpr hints.

    – Ulrich Eckhardt
    2 days ago












  • I updated the answer explaining how to automatically generate a list of all possible callback functions. You can find the right one just by packing the bools into the bits of the index

    – Jorge Perez
    2 days ago












  • The lookup table is a runtime solution. You can get the right function just by indexing into it

    – Jorge Perez
    2 days ago











  • I added code showing exactly how to do that

    – Jorge Perez
    2 days ago






  • 1





    (@$#*!) – can't find anything to criticise any more... Just kidding. But the automatically created lookup table is great, far better than my originally proposed switch statement...

    – Aconcagua
    2 days ago



















1














Leave the code as it is.



Execution time of an "if" compared to writing to std::out is practically zero, so you are arguing over nothing. Well, unless you spend some time measuring the execution time as it is, and with the if's removed according to the values of the three constants, and found that there is a real difference.



At most, you might make the function inline or static, and the compiler will probably realise the arguments are always the same when optimisation is turned on. (My compiler would give a warning that you are using a function without a prototype, which means you should have either put a prototype into a header file, telling the compiler to expect calls from other call sites, or you should have made it static, telling the compiler that it knows all the calls and can use static analysis for optimisations).



And what you think is a constant, might not stay a constant forever. The original code will work. Any new code most likely won't.






share|improve this answer






























    0














    Short of JIT compilation, you can’t do better than your 2^n functions (and the resulting binary size). You can of course use a template to avoid writing them all out. To prevent the source from scaling exponentially just from selecting the correct implementation, you can write a recursive dispatcher (demo):



    template<bool... BB>
    auto g() return f<BB...>;
    template<bool... BB,class... TT>
    auto g(bool b,TT... tt)
    return b ? g<BB...,true>(tt...) : g<BB...,false>(tt...);





    share|improve this answer

























    • If you know something at compiletime, it's easy to template it. Especially in the OP's case.

      – Jorge Perez
      2 days ago











    • @JorgePerez: I did say that you could use a template. I do realize now that you can put some of the ifs inside intermediate templates; I’ll edit that in.

      – Davis Herring
      2 days ago











    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );






    Alireza Shafaei is a new contributor. Be nice, and check out our Code of Conduct.









    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55438306%2fhow-to-avoid-run-time-checks-for-running-parts-of-code-that-become-unreachable-a%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    15














    Ensuring that if statements are evaluated at compile time



    C++17 introduces if constexpr, which does exactly this:



    template<bool task_1, bool task_2, bool task_3>
    void callback_function()
    if constexpr (task_1)
    std::cout << "Running task 1" << std::endl;

    if constexpr (task_2)
    std::cout << "Running task 2" << std::endl;

    if constexpr (task_3)
    std::cout << "Running task 3" << std::endl;




    If you have optimizations enabled, if constexpr isn't necessary. Even if you use a regular if instead of if constexpr, because the bools are now templated, the compiler will be able to eliminate the if statements entirely, and just run the tasks. If you look at the assembly produced here, you'll see that even at -O1, there are no if statements in any of the callback functions.



    We can now use callback_function directly as a function pointer, avoiding function<void()>:



    int main() 
    using callback_t = void(*)();
    callback_t func = callback_function<true, false, true>;

    // Do stuff with func



    We can also name the bools by assigning them to constexpr variables:



    int main() 
    using callback_t = void(*)();
    constexpr bool do_task1 = true;
    constexpr bool do_task2 = false;
    constexpr bool do_task3 = true;
    callback_t func = callback_function<do_task1, do_task2, do_task3>;

    // Do stuff with func



    Automatically creating a lookup table of all possible callback functions



    You mentioned choosing between different callback functions at runtime. We can do this pretty easily with a lookup table, and we can use templates to automatically create a lookup table of all possible callback functions.



    The first step is to get a callback function from a particular index:



    // void(*)() is ugly to type, so I alias it
    using callback_t = void(*)();

    // Unpacks the bits
    template<size_t index>
    constexpr auto getCallbackFromIndex() -> callback_t

    constexpr bool do_task1 = (index & 4) != 0;
    constexpr bool do_task2 = (index & 2) != 0;
    constexpr bool do_task3 = (index & 1) != 0;
    return callback_function<do_task1, do_task2, do_task3>;



    Once we can do that, we can write a function to create a lookup table from a bunch of indexes. Our lookup table will just be a std::array.



    // Create a std::array based on a list of flags
    // See https://en.cppreference.com/w/cpp/utility/integer_sequence
    // For more information
    template<size_t... Indexes>
    constexpr auto getVersionLookup(std::index_sequence<Indexes...>)
    -> std::array<callback_t, sizeof...(Indexes)>

    return getCallbackFromIndex<Indexes>()...;


    // Makes a lookup table containing all 8 possible callback functions
    constexpr auto callbackLookupTable =
    getVersionLookup(std::make_index_sequence<8>());


    Here, callbackLookupTable contains all 8 possible callback functions, where callbackLookupTable[i] expands the bits of i to get the callback. For example, if i == 6, then i's bits are 110 in binary, so



    callbackLookupTable[6] is callback_function<true, true, false>



    Using the lookup table at runtime



    Using the lookup table is really simple. We can get an index from a bunch of bools by bitshifting:



    callback_t getCallbackBasedOnTasks(bool task1, bool task2, bool task3) 
    // Get the index based on bit shifting
    int index = ((int)task1 << 2) + ((int)task2 << 1) + ((int)task3);
    // return the correct callback
    return callbackLookupTable[index];



    Example demonstrating how to read in tasks



    We can get the bools at runtime now, and just call getCallbackBasedOnTasks to get the correct callback



    int main() 
    bool t1, t2, t3;
    // Read in bools
    std::cin >> t1 >> t2 >> t3;
    // Get the callback
    callback_t func = getCallbackBasedOnTasks(t1, t2, t3);
    // Invoke the callback
    func();






    share|improve this answer

























    • The constexpr is IMHO a red herring, the important part is the use of template parameters which are evaluated at compile time. Any halfway-decent compiler is able to figure this out even without these consexpr hints.

      – Ulrich Eckhardt
      2 days ago












    • I updated the answer explaining how to automatically generate a list of all possible callback functions. You can find the right one just by packing the bools into the bits of the index

      – Jorge Perez
      2 days ago












    • The lookup table is a runtime solution. You can get the right function just by indexing into it

      – Jorge Perez
      2 days ago











    • I added code showing exactly how to do that

      – Jorge Perez
      2 days ago






    • 1





      (@$#*!) – can't find anything to criticise any more... Just kidding. But the automatically created lookup table is great, far better than my originally proposed switch statement...

      – Aconcagua
      2 days ago
















    15














    Ensuring that if statements are evaluated at compile time



    C++17 introduces if constexpr, which does exactly this:



    template<bool task_1, bool task_2, bool task_3>
    void callback_function()
    if constexpr (task_1)
    std::cout << "Running task 1" << std::endl;

    if constexpr (task_2)
    std::cout << "Running task 2" << std::endl;

    if constexpr (task_3)
    std::cout << "Running task 3" << std::endl;




    If you have optimizations enabled, if constexpr isn't necessary. Even if you use a regular if instead of if constexpr, because the bools are now templated, the compiler will be able to eliminate the if statements entirely, and just run the tasks. If you look at the assembly produced here, you'll see that even at -O1, there are no if statements in any of the callback functions.



    We can now use callback_function directly as a function pointer, avoiding function<void()>:



    int main() 
    using callback_t = void(*)();
    callback_t func = callback_function<true, false, true>;

    // Do stuff with func



    We can also name the bools by assigning them to constexpr variables:



    int main() 
    using callback_t = void(*)();
    constexpr bool do_task1 = true;
    constexpr bool do_task2 = false;
    constexpr bool do_task3 = true;
    callback_t func = callback_function<do_task1, do_task2, do_task3>;

    // Do stuff with func



    Automatically creating a lookup table of all possible callback functions



    You mentioned choosing between different callback functions at runtime. We can do this pretty easily with a lookup table, and we can use templates to automatically create a lookup table of all possible callback functions.



    The first step is to get a callback function from a particular index:



    // void(*)() is ugly to type, so I alias it
    using callback_t = void(*)();

    // Unpacks the bits
    template<size_t index>
    constexpr auto getCallbackFromIndex() -> callback_t

    constexpr bool do_task1 = (index & 4) != 0;
    constexpr bool do_task2 = (index & 2) != 0;
    constexpr bool do_task3 = (index & 1) != 0;
    return callback_function<do_task1, do_task2, do_task3>;



    Once we can do that, we can write a function to create a lookup table from a bunch of indexes. Our lookup table will just be a std::array.



    // Create a std::array based on a list of flags
    // See https://en.cppreference.com/w/cpp/utility/integer_sequence
    // For more information
    template<size_t... Indexes>
    constexpr auto getVersionLookup(std::index_sequence<Indexes...>)
    -> std::array<callback_t, sizeof...(Indexes)>

    return getCallbackFromIndex<Indexes>()...;


    // Makes a lookup table containing all 8 possible callback functions
    constexpr auto callbackLookupTable =
    getVersionLookup(std::make_index_sequence<8>());


    Here, callbackLookupTable contains all 8 possible callback functions, where callbackLookupTable[i] expands the bits of i to get the callback. For example, if i == 6, then i's bits are 110 in binary, so



    callbackLookupTable[6] is callback_function<true, true, false>



    Using the lookup table at runtime



    Using the lookup table is really simple. We can get an index from a bunch of bools by bitshifting:



    callback_t getCallbackBasedOnTasks(bool task1, bool task2, bool task3) 
    // Get the index based on bit shifting
    int index = ((int)task1 << 2) + ((int)task2 << 1) + ((int)task3);
    // return the correct callback
    return callbackLookupTable[index];



    Example demonstrating how to read in tasks



    We can get the bools at runtime now, and just call getCallbackBasedOnTasks to get the correct callback



    int main() 
    bool t1, t2, t3;
    // Read in bools
    std::cin >> t1 >> t2 >> t3;
    // Get the callback
    callback_t func = getCallbackBasedOnTasks(t1, t2, t3);
    // Invoke the callback
    func();






    share|improve this answer

























    • The constexpr is IMHO a red herring, the important part is the use of template parameters which are evaluated at compile time. Any halfway-decent compiler is able to figure this out even without these consexpr hints.

      – Ulrich Eckhardt
      2 days ago












    • I updated the answer explaining how to automatically generate a list of all possible callback functions. You can find the right one just by packing the bools into the bits of the index

      – Jorge Perez
      2 days ago












    • The lookup table is a runtime solution. You can get the right function just by indexing into it

      – Jorge Perez
      2 days ago











    • I added code showing exactly how to do that

      – Jorge Perez
      2 days ago






    • 1





      (@$#*!) – can't find anything to criticise any more... Just kidding. But the automatically created lookup table is great, far better than my originally proposed switch statement...

      – Aconcagua
      2 days ago














    15












    15








    15







    Ensuring that if statements are evaluated at compile time



    C++17 introduces if constexpr, which does exactly this:



    template<bool task_1, bool task_2, bool task_3>
    void callback_function()
    if constexpr (task_1)
    std::cout << "Running task 1" << std::endl;

    if constexpr (task_2)
    std::cout << "Running task 2" << std::endl;

    if constexpr (task_3)
    std::cout << "Running task 3" << std::endl;




    If you have optimizations enabled, if constexpr isn't necessary. Even if you use a regular if instead of if constexpr, because the bools are now templated, the compiler will be able to eliminate the if statements entirely, and just run the tasks. If you look at the assembly produced here, you'll see that even at -O1, there are no if statements in any of the callback functions.



    We can now use callback_function directly as a function pointer, avoiding function<void()>:



    int main() 
    using callback_t = void(*)();
    callback_t func = callback_function<true, false, true>;

    // Do stuff with func



    We can also name the bools by assigning them to constexpr variables:



    int main() 
    using callback_t = void(*)();
    constexpr bool do_task1 = true;
    constexpr bool do_task2 = false;
    constexpr bool do_task3 = true;
    callback_t func = callback_function<do_task1, do_task2, do_task3>;

    // Do stuff with func



    Automatically creating a lookup table of all possible callback functions



    You mentioned choosing between different callback functions at runtime. We can do this pretty easily with a lookup table, and we can use templates to automatically create a lookup table of all possible callback functions.



    The first step is to get a callback function from a particular index:



    // void(*)() is ugly to type, so I alias it
    using callback_t = void(*)();

    // Unpacks the bits
    template<size_t index>
    constexpr auto getCallbackFromIndex() -> callback_t

    constexpr bool do_task1 = (index & 4) != 0;
    constexpr bool do_task2 = (index & 2) != 0;
    constexpr bool do_task3 = (index & 1) != 0;
    return callback_function<do_task1, do_task2, do_task3>;



    Once we can do that, we can write a function to create a lookup table from a bunch of indexes. Our lookup table will just be a std::array.



    // Create a std::array based on a list of flags
    // See https://en.cppreference.com/w/cpp/utility/integer_sequence
    // For more information
    template<size_t... Indexes>
    constexpr auto getVersionLookup(std::index_sequence<Indexes...>)
    -> std::array<callback_t, sizeof...(Indexes)>

    return getCallbackFromIndex<Indexes>()...;


    // Makes a lookup table containing all 8 possible callback functions
    constexpr auto callbackLookupTable =
    getVersionLookup(std::make_index_sequence<8>());


    Here, callbackLookupTable contains all 8 possible callback functions, where callbackLookupTable[i] expands the bits of i to get the callback. For example, if i == 6, then i's bits are 110 in binary, so



    callbackLookupTable[6] is callback_function<true, true, false>



    Using the lookup table at runtime



    Using the lookup table is really simple. We can get an index from a bunch of bools by bitshifting:



    callback_t getCallbackBasedOnTasks(bool task1, bool task2, bool task3) 
    // Get the index based on bit shifting
    int index = ((int)task1 << 2) + ((int)task2 << 1) + ((int)task3);
    // return the correct callback
    return callbackLookupTable[index];



    Example demonstrating how to read in tasks



    We can get the bools at runtime now, and just call getCallbackBasedOnTasks to get the correct callback



    int main() 
    bool t1, t2, t3;
    // Read in bools
    std::cin >> t1 >> t2 >> t3;
    // Get the callback
    callback_t func = getCallbackBasedOnTasks(t1, t2, t3);
    // Invoke the callback
    func();






    share|improve this answer















    Ensuring that if statements are evaluated at compile time



    C++17 introduces if constexpr, which does exactly this:



    template<bool task_1, bool task_2, bool task_3>
    void callback_function()
    if constexpr (task_1)
    std::cout << "Running task 1" << std::endl;

    if constexpr (task_2)
    std::cout << "Running task 2" << std::endl;

    if constexpr (task_3)
    std::cout << "Running task 3" << std::endl;




    If you have optimizations enabled, if constexpr isn't necessary. Even if you use a regular if instead of if constexpr, because the bools are now templated, the compiler will be able to eliminate the if statements entirely, and just run the tasks. If you look at the assembly produced here, you'll see that even at -O1, there are no if statements in any of the callback functions.



    We can now use callback_function directly as a function pointer, avoiding function<void()>:



    int main() 
    using callback_t = void(*)();
    callback_t func = callback_function<true, false, true>;

    // Do stuff with func



    We can also name the bools by assigning them to constexpr variables:



    int main() 
    using callback_t = void(*)();
    constexpr bool do_task1 = true;
    constexpr bool do_task2 = false;
    constexpr bool do_task3 = true;
    callback_t func = callback_function<do_task1, do_task2, do_task3>;

    // Do stuff with func



    Automatically creating a lookup table of all possible callback functions



    You mentioned choosing between different callback functions at runtime. We can do this pretty easily with a lookup table, and we can use templates to automatically create a lookup table of all possible callback functions.



    The first step is to get a callback function from a particular index:



    // void(*)() is ugly to type, so I alias it
    using callback_t = void(*)();

    // Unpacks the bits
    template<size_t index>
    constexpr auto getCallbackFromIndex() -> callback_t

    constexpr bool do_task1 = (index & 4) != 0;
    constexpr bool do_task2 = (index & 2) != 0;
    constexpr bool do_task3 = (index & 1) != 0;
    return callback_function<do_task1, do_task2, do_task3>;



    Once we can do that, we can write a function to create a lookup table from a bunch of indexes. Our lookup table will just be a std::array.



    // Create a std::array based on a list of flags
    // See https://en.cppreference.com/w/cpp/utility/integer_sequence
    // For more information
    template<size_t... Indexes>
    constexpr auto getVersionLookup(std::index_sequence<Indexes...>)
    -> std::array<callback_t, sizeof...(Indexes)>

    return getCallbackFromIndex<Indexes>()...;


    // Makes a lookup table containing all 8 possible callback functions
    constexpr auto callbackLookupTable =
    getVersionLookup(std::make_index_sequence<8>());


    Here, callbackLookupTable contains all 8 possible callback functions, where callbackLookupTable[i] expands the bits of i to get the callback. For example, if i == 6, then i's bits are 110 in binary, so



    callbackLookupTable[6] is callback_function<true, true, false>



    Using the lookup table at runtime



    Using the lookup table is really simple. We can get an index from a bunch of bools by bitshifting:



    callback_t getCallbackBasedOnTasks(bool task1, bool task2, bool task3) 
    // Get the index based on bit shifting
    int index = ((int)task1 << 2) + ((int)task2 << 1) + ((int)task3);
    // return the correct callback
    return callbackLookupTable[index];



    Example demonstrating how to read in tasks



    We can get the bools at runtime now, and just call getCallbackBasedOnTasks to get the correct callback



    int main() 
    bool t1, t2, t3;
    // Read in bools
    std::cin >> t1 >> t2 >> t3;
    // Get the callback
    callback_t func = getCallbackBasedOnTasks(t1, t2, t3);
    // Invoke the callback
    func();







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited 2 days ago

























    answered 2 days ago









    Jorge PerezJorge Perez

    1,243416




    1,243416












    • The constexpr is IMHO a red herring, the important part is the use of template parameters which are evaluated at compile time. Any halfway-decent compiler is able to figure this out even without these consexpr hints.

      – Ulrich Eckhardt
      2 days ago












    • I updated the answer explaining how to automatically generate a list of all possible callback functions. You can find the right one just by packing the bools into the bits of the index

      – Jorge Perez
      2 days ago












    • The lookup table is a runtime solution. You can get the right function just by indexing into it

      – Jorge Perez
      2 days ago











    • I added code showing exactly how to do that

      – Jorge Perez
      2 days ago






    • 1





      (@$#*!) – can't find anything to criticise any more... Just kidding. But the automatically created lookup table is great, far better than my originally proposed switch statement...

      – Aconcagua
      2 days ago


















    • The constexpr is IMHO a red herring, the important part is the use of template parameters which are evaluated at compile time. Any halfway-decent compiler is able to figure this out even without these consexpr hints.

      – Ulrich Eckhardt
      2 days ago












    • I updated the answer explaining how to automatically generate a list of all possible callback functions. You can find the right one just by packing the bools into the bits of the index

      – Jorge Perez
      2 days ago












    • The lookup table is a runtime solution. You can get the right function just by indexing into it

      – Jorge Perez
      2 days ago











    • I added code showing exactly how to do that

      – Jorge Perez
      2 days ago






    • 1





      (@$#*!) – can't find anything to criticise any more... Just kidding. But the automatically created lookup table is great, far better than my originally proposed switch statement...

      – Aconcagua
      2 days ago

















    The constexpr is IMHO a red herring, the important part is the use of template parameters which are evaluated at compile time. Any halfway-decent compiler is able to figure this out even without these consexpr hints.

    – Ulrich Eckhardt
    2 days ago






    The constexpr is IMHO a red herring, the important part is the use of template parameters which are evaluated at compile time. Any halfway-decent compiler is able to figure this out even without these consexpr hints.

    – Ulrich Eckhardt
    2 days ago














    I updated the answer explaining how to automatically generate a list of all possible callback functions. You can find the right one just by packing the bools into the bits of the index

    – Jorge Perez
    2 days ago






    I updated the answer explaining how to automatically generate a list of all possible callback functions. You can find the right one just by packing the bools into the bits of the index

    – Jorge Perez
    2 days ago














    The lookup table is a runtime solution. You can get the right function just by indexing into it

    – Jorge Perez
    2 days ago





    The lookup table is a runtime solution. You can get the right function just by indexing into it

    – Jorge Perez
    2 days ago













    I added code showing exactly how to do that

    – Jorge Perez
    2 days ago





    I added code showing exactly how to do that

    – Jorge Perez
    2 days ago




    1




    1





    (@$#*!) – can't find anything to criticise any more... Just kidding. But the automatically created lookup table is great, far better than my originally proposed switch statement...

    – Aconcagua
    2 days ago






    (@$#*!) – can't find anything to criticise any more... Just kidding. But the automatically created lookup table is great, far better than my originally proposed switch statement...

    – Aconcagua
    2 days ago














    1














    Leave the code as it is.



    Execution time of an "if" compared to writing to std::out is practically zero, so you are arguing over nothing. Well, unless you spend some time measuring the execution time as it is, and with the if's removed according to the values of the three constants, and found that there is a real difference.



    At most, you might make the function inline or static, and the compiler will probably realise the arguments are always the same when optimisation is turned on. (My compiler would give a warning that you are using a function without a prototype, which means you should have either put a prototype into a header file, telling the compiler to expect calls from other call sites, or you should have made it static, telling the compiler that it knows all the calls and can use static analysis for optimisations).



    And what you think is a constant, might not stay a constant forever. The original code will work. Any new code most likely won't.






    share|improve this answer



























      1














      Leave the code as it is.



      Execution time of an "if" compared to writing to std::out is practically zero, so you are arguing over nothing. Well, unless you spend some time measuring the execution time as it is, and with the if's removed according to the values of the three constants, and found that there is a real difference.



      At most, you might make the function inline or static, and the compiler will probably realise the arguments are always the same when optimisation is turned on. (My compiler would give a warning that you are using a function without a prototype, which means you should have either put a prototype into a header file, telling the compiler to expect calls from other call sites, or you should have made it static, telling the compiler that it knows all the calls and can use static analysis for optimisations).



      And what you think is a constant, might not stay a constant forever. The original code will work. Any new code most likely won't.






      share|improve this answer

























        1












        1








        1







        Leave the code as it is.



        Execution time of an "if" compared to writing to std::out is practically zero, so you are arguing over nothing. Well, unless you spend some time measuring the execution time as it is, and with the if's removed according to the values of the three constants, and found that there is a real difference.



        At most, you might make the function inline or static, and the compiler will probably realise the arguments are always the same when optimisation is turned on. (My compiler would give a warning that you are using a function without a prototype, which means you should have either put a prototype into a header file, telling the compiler to expect calls from other call sites, or you should have made it static, telling the compiler that it knows all the calls and can use static analysis for optimisations).



        And what you think is a constant, might not stay a constant forever. The original code will work. Any new code most likely won't.






        share|improve this answer













        Leave the code as it is.



        Execution time of an "if" compared to writing to std::out is practically zero, so you are arguing over nothing. Well, unless you spend some time measuring the execution time as it is, and with the if's removed according to the values of the three constants, and found that there is a real difference.



        At most, you might make the function inline or static, and the compiler will probably realise the arguments are always the same when optimisation is turned on. (My compiler would give a warning that you are using a function without a prototype, which means you should have either put a prototype into a header file, telling the compiler to expect calls from other call sites, or you should have made it static, telling the compiler that it knows all the calls and can use static analysis for optimisations).



        And what you think is a constant, might not stay a constant forever. The original code will work. Any new code most likely won't.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 2 days ago









        gnasher729gnasher729

        42.1k44878




        42.1k44878





















            0














            Short of JIT compilation, you can’t do better than your 2^n functions (and the resulting binary size). You can of course use a template to avoid writing them all out. To prevent the source from scaling exponentially just from selecting the correct implementation, you can write a recursive dispatcher (demo):



            template<bool... BB>
            auto g() return f<BB...>;
            template<bool... BB,class... TT>
            auto g(bool b,TT... tt)
            return b ? g<BB...,true>(tt...) : g<BB...,false>(tt...);





            share|improve this answer

























            • If you know something at compiletime, it's easy to template it. Especially in the OP's case.

              – Jorge Perez
              2 days ago











            • @JorgePerez: I did say that you could use a template. I do realize now that you can put some of the ifs inside intermediate templates; I’ll edit that in.

              – Davis Herring
              2 days ago















            0














            Short of JIT compilation, you can’t do better than your 2^n functions (and the resulting binary size). You can of course use a template to avoid writing them all out. To prevent the source from scaling exponentially just from selecting the correct implementation, you can write a recursive dispatcher (demo):



            template<bool... BB>
            auto g() return f<BB...>;
            template<bool... BB,class... TT>
            auto g(bool b,TT... tt)
            return b ? g<BB...,true>(tt...) : g<BB...,false>(tt...);





            share|improve this answer

























            • If you know something at compiletime, it's easy to template it. Especially in the OP's case.

              – Jorge Perez
              2 days ago











            • @JorgePerez: I did say that you could use a template. I do realize now that you can put some of the ifs inside intermediate templates; I’ll edit that in.

              – Davis Herring
              2 days ago













            0












            0








            0







            Short of JIT compilation, you can’t do better than your 2^n functions (and the resulting binary size). You can of course use a template to avoid writing them all out. To prevent the source from scaling exponentially just from selecting the correct implementation, you can write a recursive dispatcher (demo):



            template<bool... BB>
            auto g() return f<BB...>;
            template<bool... BB,class... TT>
            auto g(bool b,TT... tt)
            return b ? g<BB...,true>(tt...) : g<BB...,false>(tt...);





            share|improve this answer















            Short of JIT compilation, you can’t do better than your 2^n functions (and the resulting binary size). You can of course use a template to avoid writing them all out. To prevent the source from scaling exponentially just from selecting the correct implementation, you can write a recursive dispatcher (demo):



            template<bool... BB>
            auto g() return f<BB...>;
            template<bool... BB,class... TT>
            auto g(bool b,TT... tt)
            return b ? g<BB...,true>(tt...) : g<BB...,false>(tt...);






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited 17 hours ago

























            answered 2 days ago









            Davis HerringDavis Herring

            8,9121736




            8,9121736












            • If you know something at compiletime, it's easy to template it. Especially in the OP's case.

              – Jorge Perez
              2 days ago











            • @JorgePerez: I did say that you could use a template. I do realize now that you can put some of the ifs inside intermediate templates; I’ll edit that in.

              – Davis Herring
              2 days ago

















            • If you know something at compiletime, it's easy to template it. Especially in the OP's case.

              – Jorge Perez
              2 days ago











            • @JorgePerez: I did say that you could use a template. I do realize now that you can put some of the ifs inside intermediate templates; I’ll edit that in.

              – Davis Herring
              2 days ago
















            If you know something at compiletime, it's easy to template it. Especially in the OP's case.

            – Jorge Perez
            2 days ago





            If you know something at compiletime, it's easy to template it. Especially in the OP's case.

            – Jorge Perez
            2 days ago













            @JorgePerez: I did say that you could use a template. I do realize now that you can put some of the ifs inside intermediate templates; I’ll edit that in.

            – Davis Herring
            2 days ago





            @JorgePerez: I did say that you could use a template. I do realize now that you can put some of the ifs inside intermediate templates; I’ll edit that in.

            – Davis Herring
            2 days ago










            Alireza Shafaei is a new contributor. Be nice, and check out our Code of Conduct.









            draft saved

            draft discarded


















            Alireza Shafaei is a new contributor. Be nice, and check out our Code of Conduct.












            Alireza Shafaei is a new contributor. Be nice, and check out our Code of Conduct.











            Alireza Shafaei is a new contributor. Be nice, and check out our Code of Conduct.














            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55438306%2fhow-to-avoid-run-time-checks-for-running-parts-of-code-that-become-unreachable-a%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Romeo and Juliet ContentsCharactersSynopsisSourcesDate and textThemes and motifsCriticism and interpretationLegacyScene by sceneSee alsoNotes and referencesSourcesExternal linksNavigation menu"Consumer Price Index (estimate) 1800–"10.2307/28710160037-3222287101610.1093/res/II.5.31910.2307/45967845967810.2307/2869925286992510.1525/jams.1982.35.3.03a00050"Dada Masilo: South African dancer who breaks the rules"10.1093/res/os-XV.57.1610.2307/28680942868094"Sweet Sorrow: Mann-Korman's Romeo and Juliet Closes Sept. 5 at MN's Ordway"the original10.2307/45957745957710.1017/CCOL0521570476.009"Ram Leela box office collections hit massive Rs 100 crore, pulverises prediction"Archived"Broadway Revival of Romeo and Juliet, Starring Orlando Bloom and Condola Rashad, Will Close Dec. 8"Archived10.1075/jhp.7.1.04hon"Wherefore art thou, Romeo? To make us laugh at Navy Pier"the original10.1093/gmo/9781561592630.article.O006772"Ram-leela Review Roundup: Critics Hail Film as Best Adaptation of Romeo and Juliet"Archived10.2307/31946310047-77293194631"Romeo and Juliet get Twitter treatment""Juliet's Nurse by Lois Leveen""Romeo and Juliet: Orlando Bloom's Broadway Debut Released in Theaters for Valentine's Day"Archived"Romeo and Juliet Has No Balcony"10.1093/gmo/9781561592630.article.O00778110.2307/2867423286742310.1076/enst.82.2.115.959510.1080/00138380601042675"A plague o' both your houses: error in GCSE exam paper forces apology""Juliet of the Five O'Clock Shadow, and Other Wonders"10.2307/33912430027-4321339124310.2307/28487440038-7134284874410.2307/29123140149-661129123144728341M"Weekender Guide: Shakespeare on The Drive""balcony"UK public library membership"romeo"UK public library membership10.1017/CCOL9780521844291"Post-Zionist Critique on Israel and the Palestinians Part III: Popular Culture"10.2307/25379071533-86140377-919X2537907"Capulets and Montagues: UK exam board admit mixing names up in Romeo and Juliet paper"Istoria Novellamente Ritrovata di Due Nobili Amanti2027/mdp.390150822329610820-750X"GCSE exam error: Board accidentally rewrites Shakespeare"10.2307/29176390149-66112917639"Exam board apologises after error in English GCSE paper which confused characters in Shakespeare's Romeo and Juliet""From Mariotto and Ganozza to Romeo and Guilietta: Metamorphoses of a Renaissance Tale"10.2307/37323537323510.2307/2867455286745510.2307/28678912867891"10 Questions for Taylor Swift"10.2307/28680922868092"Haymarket Theatre""The Zeffirelli Way: Revealing Talk by Florentine Director""Michael Smuin: 1938-2007 / Prolific dance director had showy career"The Life and Art of Edwin BoothRomeo and JulietRomeo and JulietRomeo and JulietRomeo and JulietEasy Read Romeo and JulietRomeo and Julieteeecb12003684p(data)4099369-3n8211610759dbe00d-a9e2-41a3-b2c1-977dd692899302814385X313670221313670221

            Creating closest line along the point''s azimuth using PostgreSQL Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern) Announcing the arrival of Valued Associate #679: Cesar Manara Unicorn Meta Zoo #1: Why another podcast?Drawing line between points at specific distance in PostGIS?How to efficiently find the closest point over the dateline?How to find the nearest point by using PostGIS function?PostGIS nearest point with LATERAL JOIN in PostgreSQL 9.3+Creating a table and inserting selected streets using plpgsql functionsCreating a table that stores Distances and other columnSaving select query results (year wise) from PostgreSQL/PostGIS to text filesWhat is the information behind this geometry?How to give start and end vertex ids dynamically in pgr_dijkstra?Point to Polygon nearest distance DS_distance is not using geography index & knn <-> or <#> does not give result in orderLine to point conversion with start point and end point detection?

            Crop image to path created in TikZ? Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern)Crop an inserted image?TikZ pictures does not appear in posterImage behind and beyond crop marks?Tikz picture as large as possible on A4 PageTransparency vs image compression dilemmaHow to crop background from image automatically?Image does not cropTikzexternal capturing crop marks when externalizing pgfplots?How to include image path that contains a dollar signCrop image with left size given