Rak*_*ram 9 c++ templates function return-type function-templates
#include <iostream>
using namespace std;
template <class X, class Y>
Y big(X a, Y b)
{
if (a > b)
return (a);
else return (b);
}
int main()
{
cout << big(32.8, 9);
}
Run Code Online (Sandbox Code Playgroud)
在这里,我在 CPP 中使用模板,所以当我调用函数big绕过参数double和int类型时,我想要返回答案是double. 这里的类型,它返回32而不是32.8.
我如何获得我想要的输出?如何编写正确的big函数返回类型?
for*_*818 12
一个函数只能有一种在编译时必须知道的返回类型。但是,您可以使用std::common_type, 返回两个参数都可以隐式转换为的类型。
那将是
#include <type_traits>
template <class X, class Y>
typename std::common_type<X,Y>::type big(X a, Y b)
{
if (a > b)
return a;
else return b;
}
Run Code Online (Sandbox Code Playgroud)
并检查它是否double在传递时实际返回 aint和 adouble我们可以执行以下操作:
int main() {
auto x = big(4.2,42);
std::cout << std::is_same<decltype(x),double>::value;
}
Run Code Online (Sandbox Code Playgroud)
哪个打印
1
Run Code Online (Sandbox Code Playgroud)
PS:std::common_type可以在场景后面使用三元运算符,因此这个解决方案与其他答案(auto+三元)没有太大区别。的真正威力std::common_type在于它可以接受任意数量的参数。
JeJ*_*eJo 10
返回类型必须在编译时确定。如果您仅限于c++11,则可以使用带有条件运算符的尾随返回。
template <typename X, typename Y>
auto big(X&& a, Y&& b) -> decltype(a > b ? a : b) // ---> like this
{
return a > b ? a : b;
}
Run Code Online (Sandbox Code Playgroud)
但是,如果您可以访问c++14 或更高版本,则auto返回就足够了,因为如果您将其与条件运算符一起使用,编译器将推导出正确的类型,如下所示:
template <typename X, typename Y>
auto big(X a, Y b)
{
return a > b ? a : b;
}
Run Code Online (Sandbox Code Playgroud)
在将返回类型标记为Y并将 anint作为第二个参数传递时,您已经清楚地表明这Y是一个int。这里发生的事情并没有什么意外。
#include <iostream>
template <typename X, typename Y>
decltype(auto) big(const X& a, const Y& b) // return type can just be auto as well
{
return a > b ? a : b;
}
int main()
{
std::cout << big(32.8, 9) << '\n';
std::cout << big(9, 32.8) << '\n';
std::cout << big(32.8, 90) << '\n';
std::cout << big(90, 32.8) << '\n';
}
Run Code Online (Sandbox Code Playgroud)
这会将所有四个正确值打印到屏幕上。
需要注意的一件事是,这仅适用于可以相互比较的类型,即编译器将隐式地将一种类型转换为另一种类型以进行比较。
重要提示:需要通过引用获取参数以避免未定义的行为。这与我顽固地坚持的返回类型有关。decltype(auto)可以返回对类型的引用。如果您返回函数的本地内容(参数计数),则会得到未定义的行为。