Потому что, как говорится в ошибке, Non_t
не имеет типа с именем Head
. Тот факт, что ваш оператор using Head = ...
приходит после вашего возврата, не имеет никакого значения.
Давайте рассмотрим пример счетчика.
int main() {
int i = 2;
return i;
i.thisIsNotValid();
}
Здесь мы получим ошибку компиляции. Неважно, что мы никогда не достигнем этой части кода во время выполнения. Компилятор не учитывает это. Он просто проверяет правильность всего написанного кода и генерирует для него машинный код.
С другой стороны, используя блоки if constexpr
и else
, мы сообщаем компилятору вычислить что-то во время компиляции и используйте только одну из веток. Другая полностью отбрасывается.
template<typename TTypeList, typename TWanted>
void dispatch()
{
if constexpr (std::is_same<TTypeList, Non_t>::value)
{
std::cout << "Not found :( " << std::endl;
return;
} else {
using Head = typename TTypeList::Head;
using Tail = typename TTypeList::Tail;
using Wanted = TWanted;
if constexpr (!std::is_same<Head, Wanted>::value)
{
dispatch<Tail, Wanted>();
}
else
{
std::cout << "It works" << std::endl;
}
}
}
Теперь нижняя часть функции будет полностью отброшена во время компиляции , если условие истинно.