auto if if语句不会返回值

时间:2017-01-08 18:43:16

标签: c++

我制作了一个模板和一个 自动 函数,用于比较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);
}

有什么区别?为什么第一个代码不会编译? 谢谢。

3 个答案:

答案 0 :(得分:8)

一个函数只能有一个return类型。使用return类型推导意味着它将根据解析器看到的第一个 return语句中的表达式类型推断出来。如果后来的return语句不返回相同类型的表达式,那么该函数被认为是自相矛盾的,因而形成了错误。

在第二种情况下,?:基于基于第二和第三子表达式确定的公共类型来确定表达式的类型。这两个子表达式将转换为这种常见类型。

这与return类型演绎的工作方式不同。如果您打算第一种情况起作用,那么您需要显式将返回的值转换为所需的返回类型。

答案 1 :(得分:0)

正如你用c ++ 11标记提出这个问题,我想你正在使用C ++ 11。不幸的是,C ++ 11标准规定自动类型推导(也适用于lambdas)仅限于单个语句。

由于?:运算符是表达式而不是语句,所以当if-else是一个语句并且不符合要求时,这将有效。

如果您要使用C ++ 14标准编译此代码,您将看到它应该编译这两种情况,因为此限制已被删除。

答案 2 :(得分:0)

直到昨天(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对上面没有任何问题。试试你想要说服自己的在线网站......