小议C++函数签名与模板返回类型

这篇具有很好参考价值的文章主要介绍了小议C++函数签名与模板返回类型。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

题记:什么事情都要追问一个为什么,真正理解了为什么,才能活学活用。

代码1

下面的代码能编译通过吗?

#include <stdio.h>
#include <stdlib.h>

class X
{
public:
    int *get() { return new int(); }
    double *get() { return new double(); }
};

int main()
{
    int * v1 = X().get();
    double * v2 = X().get();
    return 0;
}

答案肯定是编译不过。因为下面两个函数的“签名”是一样的:

    int *get();
    double *get();

在 C++ 语言中,函数签名包含函数名称、函数参数类型、函数参数个数等信息,但是不包含返回值类型。

代码2

下面的代码能编译通过吗?

#include <stdio.h>
#include <stdlib.h>

class X
{
public:
  template <class T>
  T *get() { return new T(); }
};

int main()
{
  int * v1 = X().get<int>();
  double * v2 = X().get<double>();
  return 0;
}

答案是可以编译通过!这是为什么呢????难道 X 这个模板对象展开后,不是展开成类似下面的样子吗:

class X
{
public:
    int *get() { return new int(); }
    double *get() { return new double(); }
};

按照 代码1 的分析和结论,这样是编译不过的才对呀!

解惑

C++ 标准里是明确定义了,函数签名不包含返回值类型。但是,为什么要这样定义呢?原因如下:

虽然,下面的调用理论上编译器是可以帮忙选出正确函数:

    int * v1 = X().get();
    double * v2 = X().get();

但是,下面的场景编译器就会犯糊涂:

X().get();

不使用返回值的调用方式 C++ 是允许的,但是这种情况下,编译器应该为它链接哪一个函数呢?编译器也不知道!正是因为存在这种不好解析的场景存在,C++才把“返回值类型”从函数签名中剔除。

明白了这个道理,就不难理解 ** 代码2 ** 为何可以编译通过了。下面的调用不存在任何二义性,所以编译器才允许模板函数中使用模板参数定义返回值类型。

    X().get<int>();
    X().get<double>();

使用 nm 工具可以看到,编译之后类型信息也加入到符号中了:
小议C++函数签名与模板返回类型
小议C++函数签名与模板返回类型

你学废了吗?

补充资料

并不是所有语言都不允许返回值类型作为函数签名的。比如 Swift 语言。那么它是如何解决二义性问题的呢?很简单,针对 X().get() 这种调用直接报错!除非提供足够信息帮助编译器正确推导出完整签名。

func some() -> Bool {
    return true;
}

func some() -> Int {
    return 1;
}

// 编译成功,编译器可以找到正确的函数
let valBool: Bool = some()
let valInt: Int = some()

// 编译失败,编译器无法确定应该使用哪个函数
some()

参考资料:Stack Overflow: Why is the return type of method not included in the method-signature?文章来源地址https://www.toymoban.com/news/detail-473284.html

到了这里,关于小议C++函数签名与模板返回类型的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C++】什么是函数模板/类模板?

    函数模板简单来说就是一个模板,与函数参数的类型无关,是一个模子,不是真正的函数,实例化的函数会根据实参的类型 自动 推导类型。 函数模板是一个模板,并不是真正的函数,它是根据传递过来的实参的类型实例化一个具体的函数,相当于我们将重复的事情交给了编

    2024年02月07日
    浏览(29)
  • TypeScript 获取函数的参数类型、返回值类型

    事例: 使用预定义的 Parameters 可以获取到一个函数的参数类型列表。 获取 test 函数的参数类型: 获取 idx 参数的类型: 我们看一下 Parameters 的定义: 我们可以看到,其实它主要是通过 infer P 获取到 T 的参数类型列表 P 并返回,如果 T 不是函数则返回 never 。 使用预定义的

    2024年02月09日
    浏览(24)
  • 【Python】函数进阶 ① ( 函数返回多个返回值 | 函数参数传递类型简介 | 位置参数 | 关键字参数 )

    在函数中 , 如果要 返回 多个返回值 , 可以 在 return 语句中 , 设置多个返回值 , 这些返回值之间使用 逗号 隔开 , 这些返回值的类型是 元组 tuple 类型的 ; 在下面的代码中 , 返回了 3 个返回值 , 其 本质上是返回了一个包含 3 个元素的 元组 数据容器 , 可以使用多重赋值将返回的

    2024年02月11日
    浏览(37)
  • C语言:当函数定义时遗漏函数返回值类型以及函数遗漏return语句

    相关阅读 C语言 https://blog.csdn.net/weixin_45791458/category_12423166.html?spm=1001.2014.3001.5482          函数定义时需要明确给出返回值的类型,比如int main();表示主函数返回一个整数值,void func();表示func函数不返回值(但会函数也会返回,这是需要区分的)。         void main();这种写法

    2024年02月19日
    浏览(27)
  • Rust main 函数返回值类型不能是 String

    是的,Rust 的 main 函数返回值类型不能是 String 。 Rust 的 main 函数只能返回以下几种类型之一: () :表示空类型,不返回任何值。 i32 :表示程序的退出码,通常非零值表示执行失败,0 表示执行成功。 std::process::ExitCode :是一个枚举类型,包含成功和失败两种情况。 实现了

    2024年02月03日
    浏览(33)
  • UE4/5C++多线程插件制作(十五、将模板统一,修改统一后的其他类,修改继承,修改返回类型等)

    目录 MTPManageBase.h MTPAbandonable.h MTPAbandonableManage.h MTPThreadInterface.h MTPThreadAgendyManage.h MTPThreadTaskManage.h MTPManage.cpp

    2024年02月15日
    浏览(34)
  • 【C++】模板进阶——非类型模板参数、模板特化、模板分离编译

    模板参数分为类型形参 与 非类型形参 类型形参 :出现在模板参数列表中,跟在class或者typedename之类的参数类型名称。 非类型形参 :用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当成常量来使用。 非类型模板参数的优势: 有些容器需要在创建对象

    2024年02月01日
    浏览(32)
  • 【C++干货铺】非类型模板 | 模板特化 | 模板分离编译

    ========================================================================= 个人主页点击直达: 小白不是程序媛 C++系列专栏: C++干货铺 代码仓库: Gitee ========================================================================= 目录 非类型模板参数 模板的特化 什么是模板特化? 函数模板特化 类模板的特化 全

    2024年02月04日
    浏览(36)
  • 【C++初阶(十)】C++模板(进阶) ---非类型模板参数、模板的特化以及模板的分离编译

    本专栏内容为:C++学习专栏,分为初阶和进阶两部分。 通过本专栏的深入学习,你可以了解并掌握C++。 💓博主csdn个人主页:小小unicorn ⏩专栏分类:C++ 🚚代码仓库:小小unicorn的代码仓库🚚 🌹🌹🌹关注我带你学习编程知识 模板参数可分为类型形参和非类型形参。 类型形

    2024年01月18日
    浏览(22)
  • 【C++】模板进阶--非类型模板参数&&模板特化及分离编译

    模板参数分为 类型形参 与 非类型形参 ,其中,类型形参即出现在模板参数列表中,跟在class或者typename之类的参数类型名称,非类型形参,就是用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当成常量来使用 我们以定义一个静态的数组为例,在没有非

    2023年04月23日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包