Возвращаемый тип при if constexpr



Ещё одним интересным местом функционала if constexpr, является возможность возвращения совершенно разных типов из одной функции (естественно, не одновременно). То есть с использованием if constexpr мы можем иметь несколько return выражений, каждое из которых возвращает объект типа, который не конвертируется в другой. Разумеется, все такие return должны быть спрятаны в блоки кода, которые будут выбрасываться на этапе компиляции.



Представим, что вы захотели совершить пакость и посмеяться над своими тиммейтами. Вы написали функцию GetStringNumber, которая возвращает строковое представление числа, которое вы в него передали. Но вы затеяли подлянку, и если в функцию передать строку с числом, то она попытается вернуть его в виде интегрального типа. Типа у коллег код похерится, если они случайно передадут туда строку. Эта функция будет выглядеть примерно так:



template <typename T>

auto GetStringNumber(T val)

{

if constexpr (std::is_arithmetic_v<T>)

return std::to_string(val);

else if constexpr(std::is_same_v<T, std::string>)

return std::stoi(val);

}


Здесь мы используем фичу С++14, благодаря которой компилятор сам выводит тип возвращаемого значения.



Очевидно, что для различных веток, функция GetStringNumber будет иметь разный тип возвращаемого значения: в первом случае std::string, а во втором int. И это работает! Правда, мы легко можем всё сломать, для этого достаточно добавить ещё один return, находящийся вне условий, который будет несовместим с двумя прочими. Если мы перестараемся со своими шаловливыми мыслями, то можем написать и что-то такое:



template <typename T>

auto GetStringNumber(T val)

{

if constexpr (std::is_arithmetic_v<T>)

return std::to_string(val);

else if constexpr(std::is_same_v<T, std::string>)

return std::stoi(val);

return std::vector<std::string>{"Joke has gone too far"};

}




Такой код уже, очевидно, не соберётся. Потому что ветки условия будут возвращать типы, не приводимые к тому, что мы возвращаем в самом конце. Это в плюсах делать запрещено.



Такая вот интересная особенность нашлась. Поделитесь им в комментариях практическими примерами использования if constexpr. Думаю, многим пригодится опыт наших замечательных комментаторов)



Apply things in an unusual ways. Stay cool.



#cpp17 #cpp14 #template