Auto Функция с if Statement не вернет значение

Я создал шаблон и функцию auto, которая сравнивает 2 значения и возвращает самый маленький. Это мой код:

#include <iostream>
using namespace std;

// Template with a value returning function: PrintSmaller
template <typename T, typename U>
auto PrintSmaller(T NumOne, U NumTwo) {
    if (NumOne > NumTwo) {
        return NumTwo;
    }
    else {
        return NumOne;
    }
}

int main() {

    int iA = 345;
    float fB = 23.4243;

    cout << PrintSmaller(iA, fB) << endl;
    cout << PrintSmaller(fB, iA) << endl;

    return 0;
}

Но он не будет компилироваться, я получаю эту ошибку на VS 2015: Ошибка C3487 'int': все возвращаемые выражения должны выводиться в один и тот же тип: ранее это было 'float'

Однако, если я удалю оператор if и напишу функцию PrintSmaller, как это, он будет работать без проблем:

auto PrintSmaller(T NumOne, U NumTwo) {
return (NumOne < NumTwo ? NumOne : NumTwo);
}

В чем разница? и почему первый код не будет компилироваться? Спасибо.

+4
08 янв. '17 в 18:43
источник поделиться
3 ответа

Функция может иметь только один тип return. Использование вывода return означает, что он будет выведен на основе типа выражения в первом выражении return, которое видит синтаксический анализатор. Если более поздние операторы return не возвращают выражения одного и того же типа, то функция считается самопротиворечивой и, следовательно, плохо сформирована.

Во втором случае ?: определяет тип выражения на основе общего типа, определенного на основе второго и третьего подвыражений. Два подвыражения будут преобразованы в этот общий тип.

Это отличается от того, как работает дедукция типа return. Если вы хотите, чтобы ваш первый случай работал, вам нужно явно преобразовать возвращаемое значение в желаемый тип возвращаемого значения.

+8
08 янв. '17 в 18:47
источник

До вчерашнего дня (2017-12-06) это не компилировалось в MSVC. Но после обновления VS 15.5 это делает.

    auto msvc_does_compile = [](auto _string)
     {
      using string_type = decltype(_string);
      return std::vector<string_type>{};
     };
   /*
    OK since VS 2017 15.5 update
   auto vec1 = msvc_does_compile( std::string{} );
   */

Добавление явного возвращаемого типа захлебнет MSVC, но не gcc/clang, как обычно:

auto msvc_does_not_compile = [](auto _string)
    // explicit return type makes msvc not to compile
    -> std::vector< decltype(_string) >
  {
    using string_type = decltype(_string);
    return std::vector<string_type>{};
  };

И то же самое, но более простое, будет остановлено даже на этапе IDE:

    auto msvc_ide_does_not_allow = []( bool wide )
    {
       if (wide)
        return std::vector<std::string>();

        return std::vector<std::wstring>();
    };

Да, опять же, эта проблемная пара gcc/clang не имеет проблем с вышеуказанным. Попробуйте какой-нибудь онлайн идеал, который вы предпочитаете убедить себя...

0
07 дек. '17 в 7:52
источник

Связанные вопросы


Похожие вопросы

Как вы задали этот вопрос с маркером С++ 11, я полагаю, вы используете С++ 11. К сожалению, в стандарте С++ 11 указывается, что вывод автоматического типа (также для лямбда) ограничен одним утверждением.

Поскольку оператор ?: является выражением вместо оператора, это будет работать, а if-else - это утверждение и не соответствует требованиям.

Если вы скомпилируете этот код со стандартом С++ 14, вы увидите, что он должен скомпилировать оба случая, поскольку это ограничение было удалено.

0
08 янв. '17 в 19:00
источник

Посмотрите другие вопросы по метке или Задайте вопрос