gpt4 book ai didi

c++ - 终极功能模板?

转载 作者:搜寻专家 更新时间:2023-10-31 00:33:18 24 4
gpt4 key购买 nike

我今天刚刚开始讨论函数模板,我对前景感到兴奋。

假设我有这样的东西:

template <class T>

T findGreater(T t1, T t2) { return (t1 > t2) ? t1 : t2; }

我可以将两个整数或两个 double 传递给函数,但是有什么最终的东西可以像我可以传递一个整数和一个 double 那样返回更大的那个吗?我知道我们会遇到函数的一些歧义错误,但是有没有一种很好的、​​流畅的方法来实现这个最终的模板功能?

最佳答案

can pass an int and a double....

一个模板函数中可以有多个模板类型,是的:

template <typename LHT, typename RHT>
// ... function definition

...and it just returns the greater one

那么这个函数的返回类型是什么?返回类型是每个函数声明的一部分,必须在编译时确定。所以返回类型不能依赖于传递给它的参数的

你可以有以下内容:

template <typename LHT, typename RHT>
LHT findGreater(LHT lhs, RHT rhs) { // ...etc...

...假设 LHT 是可接受的返回类型;如果 LHT 是整数但 RHT 是 float 的,您将失去精度。

在 C++11 及更高版本中,您可以使用 decltype,这应该可以防止您丢失精度:

template <typename LHT, typename RHT>
auto findGreater(LHT lhs, RHT rhs) -> decltype(lhs + rhs) { // ...etc...

在这里,我使用了 + 运算符,因为无论参数的顺序如何,它都会解析为更高精度的类型。

但是,如果您只是使用 decltype((lhs > rhs) ? lhs : rhs) 而不是 + 呢?在这里,通过简单地将函数体复制到 decltype 表达式中,您实质上是在告诉编译器“此函数返回的返回类型”,也就是……究竟是什么?

嗯,三元表达式的类型是 common type of its arguments ;对于内置数字类型,这意味着将提升低精度类型。所以这似乎等同于使用 +

但是,在 C++ 中(与 C 不同),三元运算符可以 evaluate to lvalues ; decltype 总是推导出左值的 reference 类型,因此如果 LHTRHT 是同一类型,函数将返回lhsrhs 的引用

有两种解决方法:

  • 在 C++14 及更高版本中,您可以省略 decltype,只要函数在声明的地方定义即可。 auto 为左值三元运算符计算推导出引用类型。
  • decltype 上使用 std::decay 以确保它解析为引用:

    template <typename LHT, typename RHT>
    auto findGreater(LHT lhs, RHT rhs)
    -> typename std::decay<decltype((lhs > rhs) ? lhs : rhs)>::type
    {
    return (lhs > rhs) ? lhs : rhs;
    }
  • 通过引用传递您的参数并有意返回一个引用。这看起来像这样:

    template <typename LHT, typename RHT>
    auto& findGreater(LHT& lhs, RHT& rhs)
    {
    return (lhs > rhs) ? lhs : rhs;
    }

    请注意,我在这里明确选择了 auto& 作为返回类型。这确保返回类型是引用类型,即使 LHTRHT 是不同的类型(即如果 decltype((lhs > rhs) ? lhs : rhs) 不计算为引用类型)。这在 C++11 中显然可行;请参阅下面的评论。

关于c++ - 终极功能模板?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29057536/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com