C++函数重载的一点问题
问题
#include <iostream>
#include <vector>
enum A { Value = 1 };
void a(std::vector<int>) {
std::cout << "a1" << std::endl;
}
void a(A e) {
std::cout << "a2:" << e << std::endl;
}
//void a(int t) {
// std::cout << "a3:" << t << std::endl;
//}
int main() {
a({});
// a({1});
// a({Value});
// a({1,2});
return 0;
}
这段代码,想想会输出哪个?
我会选择输出 a1,我想应该有很多人跟我的选择是一致的。
因为按照C的习惯,enum A 实际上可能是一个整形,而{}最可能的是个数组,
最符合直觉的结果肯定是输出a1
但实际上,无论用g++还是clang++,输出的结果都是 a2:0
分析
接着上面的代码,如果在main中写下面的代码:
A c = {};
std::cout << "A:" << c << std::endl;
它会编译通过,并始终输出A:0,这证明enum是可以用{}初始化的
那其他类型呢?
是的,几乎所有的基础类型都可以
显然,编译器认为,初始化一个enum A,比初始化一个std::vector<int>要简单,
在函数重载中,void a(A e)是一个更直接的匹配
同样如果注释void a(A e)函数,将void a(int t)解注释,应该知道会输出什么结果了。
思考1
这让我想起了int i(1);这种直接初始化方式。那这与上面的列表初始化有什么不同?
int i = 1.1; // 正确
int i = {1.1}; // 编译错误
int i(1.1); // 正确
由此可见,列表初始化会显得更安全,因为它禁止窄化转换,推荐在需要严格类型检查时使用。
但是在c中,有不同的情况
int i = 1.1; // 正确
int i = {1.1}; // 正确
int i(1.1); // 错误
显然,c支持基础类型的列表初始化,并且c也允许a((int){1.1});这种调用方式,这样语言的语法才是自洽完整的。
所以,如果一开始的问题答错了,其实跟c++关系不大,而是对c的认知还差点意思,咱还得学习。
所谓活到老,学到老
结论
在调用重载函数时,需要当心!!!不然很容易出一些难以查找的BUG
C++函数重载的一点问题的更多相关文章
- C++学习笔记之模板(1)——从函数重载到函数模板
一.函数重载 因为函数重载比较容易理解,并且非常有助于我们理解函数模板的意义,所以这里我们先来用一个经典的例子展示为什么要使用函数重载,这比读文字定义有效的多. 现在我们编写一个交换两个int变量值得 ...
- 函数定义从零开始学C++之从C到C++(一):const与#define、结构体对齐、函数重载name mangling、new/delete 等
今天一直在学习函数定义之类的问题,下午正好有机会和大家共享一下. 一.bool 类型 逻辑型也称布尔型,其取值为true(逻辑真)和false(逻辑假),存储字节数在不同编译系统中可能有所不同,VC+ ...
- C++默认参数与函数重载 注意事项
一.默认参数在C++中,可以为参数指定默认值.在函数调用时没有指定与形参相对应的实参时, 就自动使用默认参数. 默认参数的语法与使用:(1)在函数声明或定义时,直接对参数赋值.这就是默认参数:(2)在 ...
- DELPHI语法基础学习笔记-Windows 句柄、回调函数、函数重载等(Delphi中很少需要直接使用句柄,因为句柄藏在窗体、 位图及其他Delphi 对象的内部)
函数重载重载的思想很简单:编译器允许你用同一名字定义多个函数或过程,只要它们所带的参数不同.实际上,编译器是通过检测参数来确定需要调用的例程.下面是从VCL 的数学单元(Math Unit)中摘录的一 ...
- C++实验二——函数重载、函数模板、简单类的定义和实现
一.实验过程 函数重载编程练习 实验要求:编写重载函数add(),实现对int型,double型,complex型数据的加法.在main函数中定义不同类型的数据,调用测试. 代码实现: 先是简单的体验 ...
- C++ 继承、函数重载
题外话1:浪费了两天,可耻! 题外话2:你这个年纪,做得好是理所当然,做不好是罪孽深重!!! --- 深以为然. 题外话3:从开始看C++ Primer 到现在,整整24天了,没想到基础方面耗费这么久 ...
- const与#define、结构体对齐、函数重载name mangling、new/delete 等
一.bool 类型 逻辑型也称布尔型,其取值为true(逻辑真)和false(逻辑假),存储字节数在不同编译系统中可能有所不同,VC++中为1个字节. 声明方式:bool result; result ...
- 函数重载(overload)和函数重写(override)
1. 前言: 在C++中有两个非常容易混淆的概念,分别是函数重载(overload)和函数重写(overwirte).虽然只相差一个字,但是它们两者之间的差别还是非常巨大的. 而通过深入了解这两个概念 ...
- C++默认函数与函数重载
一.默认参数 在C++中,可以为参数指定默认值.在函数调用时没有指定与形参相对应的实参时, 就自动使用默认参数. 默认参数的语法与使用:(1)在函数声明或定义时,直接对参数赋值.这就是默认参数: (2 ...
- c++学习笔记之函数重载和模板理解
1.函数重载: C++ 不允许变量重名,但是允许多个函数取相同的名字,只要参数表不同即可,这叫作函数的重载(其英文是 overload).重载就是装载多种东西的意思,即同一个事物能完成不同功能. 所谓 ...
随机推荐
- Vulnhub-Hackme
一.靶机搭建 选择扫描虚拟机 选择路径即可 二.信息收集 靶机信息 Name: hackme: 1 Date release: 18 Jul 2019 难度:初级,目标是通过web漏洞获得有限的权限访 ...
- sap 管理--企业解决方案 -设备管理
1.什么是sap 管理 2.设备管理管的是什么 3.设备的几种状态 4.设备bom(物料清单) 5.测量点计数器 1.什么是sap 管理 System Applications and Product ...
- Windows编程----CreateProcess函数
CreateProcess函数原型 CreateProcess 函数用于创建一个新进程(子进程)及其主线程,其函数原型如下: BOOL CreateProcess( LPCWSTR lpApplica ...
- Font-awesome失效恢复
Font-awesome失效恢复策略 可能的原因有: 1.用了收费pro的版本,没充钱. Font Awesome 6 字体分为 Free 和 Pro 两个版本.Font Awesome 6 Free ...
- 一款基于.NET开源、强大的网络管理和网络问题排查工具!
前言 今天大姚给大家分享一款基于.NET开源.免费.功能强大的网络管理和网络问题排查工具:NETworkManager. 项目介绍 NETworkManager 是一个基于.NET开源(GPL-3.0 ...
- Golang windows下 交叉编译
前言 在进行Go开发的时候,go env 可以设置Go的环境变量信息 GOOS 的默认值是我们当前的操作系统, 如果 windows,linux,注意 mac os 操作的上的值是darwin. GO ...
- Netty源码—2.Reactor线程模型一
大纲 1.关于NioEventLoop的问题整理 2.理解Reactor线程模型主要分三部分 3.NioEventLoop的创建 4.NioEventLoop的启动 1.关于NioEventLoop的 ...
- 视觉SLAM第四讲李群与李代数习题
视觉SLAM第四讲李群与李代数习题 一.验证\(SO(3).SE(3).SIM(3)\)关于乘法成群 首先引入一下群的定义. 群 (Group) 是一种集合加上一种运算的代数结构.我们把集合记作 \( ...
- 标准javabean
1.javabean介绍 javabean,名为实体类,封装数据的类 前面我们写的类都是实体类,但我们写的不是标准的实体类 . 2.标准的javabean写法 如图 3.快捷键 一个成员变量就要写两个 ...
- 【Java】RESTful风格
RESTful风格 REST:即 Representational State Transfer.(资源)表现层状态转化.是目前最流行的一种互联网软件架构.它结构清晰.符合标准.易于理解.扩展方便,所 ...