Accessing member type with `if constexpr` inside generic lambda requires both branches to be well-formed - gcc vs clang

Viewed 388

Consider two structs with different member type aliases:

struct foo { using x = int;   };
struct bar { using y = float; };

Given a T in a template context, I want to get either T::x or T::y depending on what T is:

template <typename T>
auto s()
{
    auto l = [](auto p) 
    {
        if constexpr(p) { return typename T::x{}; }
        else            { return typename T::y{}; }
    };

    return l(std::is_same<T, foo>{});
}

int main() 
{ 
    s<foo>(); 
}

g++ compiles the code above, while clang++ produces this error:

error: no type named 'y' in 'foo'
        else            { return typename T::y{}; }
                                 ~~~~~~~~~~~~^
note: in instantiation of function template specialization 's<foo>' requested here
    s<foo>();
    ^

on godbolt.org, with conformance viewer


Is clang++ incorrectly rejecting this code?

Note that clang++ accepts the code when removing the indirection through the generic lambda l:

template <typename T>
auto s()
{
    if constexpr(std::is_same<T, foo>{}) { return typename T::x{}; }
    else                                 { return typename T::y{}; }
}
1 Answers
Related