explicit和initializer_list

1、在传统用法中,explicit用于单参构造函数,阻止隐式类型转换。

cpp 复制代码
class MyClass
{
public:
    explicit MyClass(int x){}//防止隐式转换
};
void func(MyClass obj){}
int main()
{
    MyClass obj1(5);
    MyClass obj2 = 5;//错误,禁止隐式类型转换
    MyClass obj3 = MyClass(5);

    func(5);//错误,禁止隐式类型转换
    func(MyClass(5));正确
}

2、在C++11之后,允许使用在多参构造函数,阻止一致性初始化来隐式转换。

cpp 复制代码
class Point
{
public:
	explicit Point(int x, int y) :x(x), y(y) {}
private:
	int x, y;
};
void drawPoint(Point p)
{
}
int main()
{
	Point p1(1, 2);//OK 直接初始化
	Point p2 = { 1,2 };//ERROR explicit 阻止一致性初始化隐式转换
	Point p3 = Point(1, 2);//OK 显式调用构造函数

	drawPoint({ 1,2 });//ERROR explicit 阻止一致性初始化隐式转换
	drawPoint(Point(1, 2));//OK 显式调用构造函数
	return 0;
}

3、std::initializer_list是C++引入的轻量级容器,使用{}来初始化对象,用在相同类型不定数量的一致性参数初始化,比如想写一个不定个数的打印函数(变参模板功能更强大,不仅是参数个数不定,而且参数类型也可以不一致,而initializer_list要求必须相同类型的参数个数不定)。

cpp 复制代码
#include <initializer_list>
#include <iostream>
#include <string>

void printList(std::initializer_list<std::string> strs)
{
	for (auto str : strs)
	{
		std::cout << str << std::endl;
	}
}
int main()
{
	printList({ "Hello", "World", "from", "C++14" });
	printList({ "forTest1","forTest2" });
	return 0;
}

4、通常在构造函数中使用,用来创建支持一致性初始化的类。

cpp 复制代码
#include <initializer_list>
#include <iostream>
#include <string>
#include <vector>

class MyContainer
{
private:
	std::vector<int> data;
public:
	//使用一致性初始化构造函数
	MyContainer(std::initializer_list<int> init) :data(init) {}
	//使用常规构造函数
	MyContainer(int size, int value = 0) :data(size, value) {}
	void print()const
	{
		for (const auto& elem : data)
		{
			std::cout << elem << " ";
		}
		std::cout << std::endl;
	}
};
int main()
{
	MyContainer c1{ 1, 2, 3, 4, 5 }; // 调用一致性初始化构造函数
	MyContainer c2 = { 6, 7, 8, 9, 10 }; // 调用一致性初始化构造函数
	MyContainer c3(5, 10);           // 调用常规构造函数
	c1.print(); // 输出: 1 2 3 4 5
	c2.print(); // 输出: 10 10 10 10 10
	return 0;
}

5、也可以用在返回一致性初始化列表。

cpp 复制代码
#include <vector>

// 返回初始化列表(转换为其他容器)
std::vector<int> createVector() {
    return {1, 2, 3, 4, 5};  // 隐式转换
}

// 返回初始化列表自身
auto getInitList() -> std::initializer_list<int> {
    return {10, 20, 30, 40};  // 注意生命周期!
}
相关推荐
云和数据.ChenGuang38 分钟前
LangGraph 异步 Node 的设计与写法实践
开发语言·人工智能·python·机器学习·php
WL学习笔记1 小时前
vector模拟实现
c++
蜗牛一步步往上爬4 小时前
第十六章 C++语言在深度学习中的应用
开发语言·c++·深度学习
张张123y6 小时前
DSH 插件调试避坑:client.js 设置面板、热重载与高频报错排查表
开发语言·javascript·人工智能·开源·ecmascript·后端开发·ai agent
wo_jack7 小时前
C++ 入门笔记(十六):第16课 vector 模拟实现十问十答 —— 从三指针到迭代器失效
c++·后端·面试·stl·vector
D e re k ZH8 小时前
C++ 标准库算法全景指南
数据结构·c++·算法
冻柠檬飞冰走茶9 小时前
字母移动游戏题解:贪心求最长可保留连续子串(附 C 实现)
c语言·开发语言·数据结构·算法·动态规划
FRing039 小时前
vue2干货总结7(自定义指令、插槽、单页应用程序、路由的使用(VueRouter))
开发语言·前端·vue.js·vue2
雪落漂泊9 小时前
C++算法 二分查找篇(上)
开发语言·c++·算法
波力海苔夹心脆67510 小时前
C# WPF 资源字典详解:ResourceDictionary、MergedDictionaries 与自定义控件案例
开发语言·c#·wpf·入门教程·resource·资源字典