返回介绍

返回值类型后置语法

发布于 2025-02-26 23:19:57 字数 2112 浏览 0 评论 0 收藏 0

考虑下面这段代码:

template<class T, class U>
??? mul(T x, U y)
{
    return x*y;
}

函数 mul() 的返回类型要怎么写呢?当然,是“xy 类型”,但是这并不是一个数据类型,我们如何才能一开始就得到它的真实数据类型呢?在初步了解 C++0x 之后,你可能一开始想到使用 decltype 来推断“xy”的数据类型:

template<class T, class U>
decltype(x*y) mul(T x, U y) // 注意这里的作用域
{
    return x*y;
}

但是,这种方式是行不通的,因为 x 和 y 不在作用域内。但是,我们可以这样写:

template<class T, class U>
// 难看别扭,且容易产生错误
decltype(*(T*)(0)**(U*)(0)) mul(T x, U y)    
{
    return x*y;
}

如果称这种用法为“还可以”,就已经是过誉了。

C++11 的解决办法是将返回类型放在它所属的函数名的后面:

template<class T, class U>
auto mul(T x, U y) -> decltype(x*y)
{
    return x*y;
}

这里我们使用了 auto 关键字,(auto 在 C++11 中还有根据初始值推导数据类型的意义),在这里它的意思变为“返回类型将会稍后引出或指定”。

返回值后置语法最初并不是用于模板和返回值类型推导的,它实际是用于解决作用域问题的。

struct List {
    struct Link { /* ... */ };
    Link* erase(Link* p);   // 移除 p 并返回 p 之前的链接
    // ...
};

List::Link* List::erase(Link* p) { /* ... */ }

第一个 List::是必需的,这仅是因为 List 的作用域直到第二个 List::才有效。更好的表示方式是:

auto List::erase(Link* p) -> Link* { /* ... */ }

现在,将函数返回类型后置,Link*就不需要使用明确的 List::进行限定了。

参考:

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文