Функция автоматического возврата значения с помощью переключателя - PullRequest
0 голосов
/ 26 ноября 2018

Я пытаюсь создать функцию, тип возвращаемого значения которой зависит от оператора switch, например:

auto function_name (int value) {
    switch (value) {
        case 1 : {return 2.3;}
        case 2 : {return 1;}
        case 3 : {return "string";}
    }
}

Но я не могу из-за ошибки:

error: inconsistent deduction for auto return type: 'double' and then 'int'

Что я могу сделать, чтобы создать что-то похожее по функциональности на пример выше?

Ответы [ 3 ]

0 голосов
/ 26 ноября 2018

Функция в C ++ может иметь только один тип, который она возвращает.Если вы используете auto в качестве возвращаемого типа и у вас есть разные операторы возврата, которые возвращают разные типы, тогда код некорректен, так как нарушает правило одного типа.

Здесь необходимо использовать std::variant или std::any.Если у вас есть несколько различных типов, которые могут быть возвращены через некоторое значение времени выполнения, вы можете использовать любой из этих типов как «универсальный тип».std::variant является более строгим, поскольку вы должны указать типы, которые могут быть, но он также дешевле, чем std::any, потому что вы знаете, какие это могут быть типы.

std::variant<double, int, std::string> function_name (int value) {
    using namespace std::literals::string_literals;
    switch (value) {
        case 1 : {return 2.3;}
        case 2 : {return 1;}
        case 3 : {return "string"s;} // use ""s here to force it to be a std::string
    }
}

Позволит вам возвращать различные типы.

0 голосов
/ 26 ноября 2018

Если аргумент функции известен во время компиляции, вы можете использовать диспетчеризацию во время компиляции, например,

template <int N>
constexpr auto function_name()
{
   if constexpr(N == 1)
      return 2.3;
   else if constexpr (N == 2)
      return 1;
   else
      return "string";
}

, которую можно создать и вызвать следующим образом

std::cout << function_name<1>() << "\n";

C ++17 необходим для части if constexpr.Обратите внимание, что при привязке возвращаемого значения к переменной тщательно выбирайте тип (например, чтобы неявно не преобразовать double в int случайно), используйте дедукцию типа или тип variant, как показано в существующих ответах..

Обратите внимание, что, как указано в комментариях @NathanOliver, существует также решение до C ++ 17, в котором вместо if constexpr используется *1013*:

template <int N> constexpr auto function_name() { return "string"; }
template <> constexpr auto function_name<1>() { return 2.3; }
template <> constexpr auto function_name<2>() { return 1; }

Использованиеданного шаблона и его специализаций не отличается от вышеуказанных.

0 голосов
/ 26 ноября 2018

Сообщение об ошибке говорит само за себя: все ветви функции должны возвращать один и тот же тип.Это ограничение не относится к auto типу возвращаемого значения.

Одно из возможных исправлений:

std::variant<double, int, std::string> function_name(int value) {
    switch(value) {
    case 1 : return 2.3;
    case 2 : return 1;
    case 3 : return "string";
    default: throw;
    }
}

В качестве альтернативы вы можете использовать boost::variant.

...