带有 if 语句的自动函数不会返回值

auto Function with if Statement won't return a value

本文关键字:函数 返回值 if 语句 带有      更新时间:2023-10-16

我制作了一个模板和一个自动函数,用于比较 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 语句并像这样编写函数 PrintSmall,它可以毫无问题地工作:

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

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

一个函数只能有一个return类型。使用return类型推导意味着将根据解析器看到的第一个return语句中的表达式类型推导它。如果后面的return语句不返回相同类型的表达式,则该函数被认为是自相矛盾的,因此格式不正确。

在第二种情况下,?:基于基于第二个和第三个子表达式确定的通用类型确定表达式的类型。这两个子表达式将转换为此通用类型。

这与return类型扣除的工作方式不同。如果打算使第一个案例起作用,则需要将返回值显式转换为所需的返回类型。

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

由于?:运算符是表达式而不是语句,因此当if-else是语句且不符合要求时,这将起作用。

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

直到昨天(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 对上述内容没有问题。试试你喜欢说服自己的在线IDE...