如何在模板中返回正确类型的数据?

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绕过参数doubleint类型时,我想要返回答案是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

返回类型必须在编译时确定。如果您仅限于,则可以使用带有条件运算符的尾随返回

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)

看直播


但是,如果您可以访问 或更高版本,则auto返回就足够了,因为如果您将其与条件运算符一起使用,编译器将推导出正确的类型,如下所示:

template <typename X, typename Y>
auto big(X a, Y b)
{
   return  a > b ? a : b;
}
Run Code Online (Sandbox Code Playgroud)

看直播


swe*_*ish 5

在将返回类型标记为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)

这会将所有四个正确值打印到屏幕上。

https://godbolt.org/z/fyGsmo

需要注意的一件事是,这仅适用于可以相互比较的类型,即编译器将隐式地将一种类型转换为另一种类型以进行比较。

重要提示:需要通过引用获取参数以避免未定义的行为。这与我顽固地坚持的返回类型有关。decltype(auto)可以返回对类型的引用。如果您返回函数的本地内容(参数计数),则会得到未定义的行为。