我制作了一个模板和一个 自动 函数,用于比较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);
}
有什么区别?为什么第一个代码不会编译? 谢谢。
答案 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对上面没有任何问题。试试你想要说服自己的在线网站......