Можно ли передавать параметры в функцию с помощью оператора switch в c ++? - PullRequest
0 голосов
/ 29 мая 2020

Есть ли способ передавать параметры в функции с помощью операторов switch в C ++? Я пытаюсь превратить серию операторов if в один оператор switch.

В качестве примера я хотел бы превратить это:

if (function(a)) {
  //code
}

if (function(b)) {
  //code
}

if (function(c)) {
  //code
}

в это:

switch (function(a/b/c)) {
case a:
  //code
case b:
  //code
case c:
  //code
}

Функция возвращает истину или ложь в зависимости от того, активны ли a, b или c. Важно отметить, что a, b и c действительно будут константами, но сама функция будет определять, активны они в данный момент или нет. Проблема, над которой я работаю, заключается в том, нажата ли клавиша в данный момент, когда функции дается код клавиши для проверки. Это выглядит примерно так:

if (isKeyPressed(Key::A)) {
  //code
}

Возможно ли это или это нарушает суть оператора switch?

1 Ответ

1 голос
/ 29 мая 2020

Это не то, как используется switch. Вместо этого он должен выглядеть примерно так:

switch (someValue)
{
case value1:
  function(a);
  break;
case value2:
  function(b);
  break;
case value3:
  function(c);
  break;
}

Если это не то, что вы ищете, тогда оператор ?: может работать для вы, в зависимости от того, что на самом деле ваши входы, например:

function( condition1 ? a : (condition2 ? b : c) );

Или, может быть, вы пытаетесь вызвать функцию 1 раз и получить разные виды вывода в зависимости от ввода, которые вы затем можете проверить на ? Если это так, то std::variant может быть тем, что вы ищете, например:

std::variant<a,b,c> function()
{
  return ...;
}

auto v = function(input);
if (std::holds_alternative<a>(v)) {
  //code
}

else if (std::holds_alternative<b>(v)) {
  //code
}

else if (std::holds_alternative<c>(v)) {
  //code
}

Или:

auto v = function(input);
switch (v.index()) {
  case 0: // a
    //code
    break;
  case 1: // b
    //code
    break;
  case 2: // c
    //code
    break;
}

Или:

auto v = function(input);
std::visit([](auto&& arg) {
  using T = std::decay_t<decltype(arg)>;
  if constexpr (std::is_same_v<T, a>) {
    // code
  }
  else if constexpr (std::is_same_v<T, b>) {
    // code
  }
  else if constexpr (std::is_same_v<T, c>) {
    // code
  }
}, v);

Или:

template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;

auto v = function(input);
std::visit(overloaded {
  [](a arg) { /* code */ },
  [](b arg) { /* code */ },
  [](c arg) { /* code */ },
}, v);
...