lundi 18 mars 2019

if constexpr Seems to Only Work if Both Cases are Valid

Given the following code:

template<typename T>
constexpr remove_reference_t<decltype(T{}.x, bool{})> has_x() {return true;}
template<typename T, class... U>
constexpr bool has_x(U...) {return false;}

class A { public: int x; };

int main()
{
    vector<int> vec;
    A my_a{};

    std::cout << has_x<decltype(my_a)>() << endl << has_x<decltype(vec)>() << endl;

    if constexpr(has_x<decltype(vec)>())
    {
        cout << vec.x << endl;
    }
    else
    {
        cout << size(vec) << endl;
    }
}

It compiles only if I comment out the cout << vec.x << endl. This obviously won't compile, but my understanding from if constexpr was that:

If the value is true, then statement-false is discarded (if present), otherwise, statement-true is discarded

Thus I thought that "statement-true" should be discarded, but this doesn't seem to be the case. If I put a statement that's valid in either case in the "statement-true" it works. But with a potentially invalid statement I get:

error: class std::vector<int> has no member named x

Am I doing something wrong here?

Live Example





Aucun commentaire:

Enregistrer un commentaire