Как указать выведенный (автоматический) тип возвращаемого значения в ветке if constexpr, которая всегда выдает ошибку?

Как я могу указать тип возвращаемого значения функции с выведенным (auto) типом возвращаемого значения, если тело содержит несколько ветвей if constexpr и одна из них безоговорочно выбрасывает?

Тип возвращаемого значения должен удовлетворять определенной концепции; Я не могу просто оставить это как void.

Я пробовал использовать std::declval, но статический g++ утверждает меня: «Вы не можете использовать declval».

Вопрос в том, есть ли лучший способ объявить возвращаемый тип, кроме ложного возврата?

auto func()
{
   if constexpr (A)
   {
      if (...) return std::vector<int>{}; // actually something difficult to initialize
   }
   if constexpr (A && C)
   {
      throw 5;
      // fake return to declare return type - same type as if constexpr (A) above
      // return std::move(std::declval<std::vector<int>>()); // static assert in std library
      return std::move(*static_cast<std::vector<int>*>(nullptr)); // it works! is there any better way?
   }
   else return std::array<double, 5>{}; 
}

Честно говоря, это немного проблематично. «Конкретную концепцию», которая не применима к пустоте, я бы лично попытался пересмотреть в первую очередь.

StoryTeller - Unslander Monica 05.09.2024 19:38

Принимает ли фактическая функция аргумент? Можно ли использовать шаблоны? Как насчет концепций C++20? Перегрузка? Специализация шаблона?

Some programmer dude 05.09.2024 19:38

Я бы объявил помощника типа template <typename T> [[noreturn]] inline static T never() { std::unreachable(); }, а затем просто return never<std::vector<int>>();.`

user3840170 05.09.2024 19:47

@user3840170 user3840170 — встроенный или статический. В противном случае это просто многословный способ сказать static. Это также отличный ответ в C++17, если вы используете std::exit вместо std::unreachable.

StoryTeller - Unslander Monica 05.09.2024 19:51

Примечание: вместо того, чтобы бросать, вы можете рассмотреть возможность возврата std::expected.

Pepijn Kramer 05.09.2024 20:49

@Someprogrammerdude Фактическая функция принимает параметры и пакет параметров, это шаблонная функция в шаблонном классе, и я работаю с C++26. Функция может возвращать МНОГО разных типов, но все они удовлетворяют одной и той же концепции.

Chameleon 05.09.2024 22:43
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
6
64
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Хотя я бы сказал, что эта предпосылка шаткая, вы можете создать для нее кладж с помощью немедленно вызываемой лямбды.

return []() -> std::vector<int> { throw 5; }();

Лямбда действительна (хотя и загадочна), поскольку ее тело никогда не переходит в конец, вызывая неопределенное поведение. А явный возвращаемый тип придает всему выражению тот тип, который мы хотим получить в операторе return.

Вы также можете превратить это в вспомогательный шаблон, как предложено в комментариях к вашему вопросу.

Другие вопросы по теме