Рассмотрим два 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{}; }
}