Рассмотрим два struct с разными псевдонимами типа элемента:
struct foo { using x = int; };
struct bar { using y = float; };
Учитывая T в контексте template, я хочу получить либо T::x, либо T::y в зависимости от того, что T:
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++ компилирует код выше, а clang++ вызывает эту ошибку:
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>();
^
на godbolt.org, с просмотром соответствия
Неправильно ли отклоняется clang++ этот код?
Обратите внимание, что clang++ принимает код при удалении косвенности через общий лямбда l:
template <typename T>
auto s()
{
if constexpr(std::is_same<T, foo>{}) { return typename T::x{}; }
else { return typename T::y{}; }
}