vendredi 11 janvier 2019

Why does if statement fail in member function that calls a constexpr member function?

I have a simple class as such:

class Foo {
public:
    enum InputType {
        IT_0 = 0,
        IT_1,
        IT_2
    };

    enum OutputType {
        OT_0 = 123,
        OT_1 = 234,
        OT_2 = 345
    };

    static uint16_t update( uint8_t input ) {
        if ( input == IR_0 )
            return updater<OT_0>();
        if ( input == IR_1 )
            return updater<OT_1>();
        if ( input == IR_2 )
            return updater<OT_2>();

        return IR_0; // default type
    }

    template<const uint8_t In>
    static constexpr uint16_t updater() {

        if constexpr( In == OR_0 ) {
            // std::cout << "Output updated to: " << OT_0 << '\n;
            return OT_0;
        }

        if constexpr( In == OR_1 ) {
           // std::cout << "Output updated to: " << OT_1 << '\n';
           return OT_1;
        }

        if constexpr( In == OR_2 ) {
            // std::cout << "Output updated to: " << OT_2 << '\n';
            return OT_2;
        }
    }
};

I can use the function template by itself as such when the values are known at compile time and get the expected results:

#include <iostream>

int main() {
    const uint16_t output0 = Foo::updater<InputType::IT_0>();
    const uint16_t output1 = Foo::updater<InputType::IT_1>();
    const uint16_t output2 = Foo::updater<InputType::IT_2>();

    std::cout << "\n--------------------------------\n";
    std::cout << "Output0: " << output0 << '\n'
              << "Output1: " << output1 << '\n'
              << "Output2: " << output2<< '\n';

    return 0;
}

And I get the expected output with the cout statements in the function template uncommented:

-Output-

Output updated to: 123
Output updated to: 234
Output updated to: 345

-------------------------------
Output0: 123
Output1: 234
Output2: 345

Everything seems to be okay so far.


However when I try to use this function within another member of the class where the values are determined by runtime, it doesn't appear that I am having a problem with the constexpr function template, but rather the non constexpr function evaluating its if statements' conditions to true and executing the code within the if statements as such:

<iostream>

int main() {
    uint8_t input;
    std::cout << "Please enter input value [0,2]\n";
    std::cin >> input;

    auto output = Foo::update( input );

    std::cout << "Ouput: " << output << '\n';

    return 0;

}

Every time I run this version it is failing to fall into the if statements and is always reporting back the default return with a value of 123. I even tried to static_cast from one to the other and vice versa and it still fails. I do not know what I am missing or overlooking.

Aucun commentaire:

Enregistrer un commentaire