c++可变长度对象(vector,map)作为struct成员

以前,C语言写结构体时。结构体成员都是基本类型,比如int、char、double之类的,最多也就里边再套一个结构体成员,但它们都有一个特点。它们的大小是固定的,我不会有这样的担心。但是,我接触到string、vector这些类类型时,根据它们的特性:它们能动态扩充,就是你来多少内容,我都能存的下!

       然后,我就想:那它们的变量大小是不是也扩充了,那是不是也导致所处的结构体的变量的大小也改变了呢?

 

       因此,我查了下书。找到了答案:总结一下,简单来说就是,这些动态可变更存储长度的类都是使用指针,附加动态申请内存实现的而动态申请的内存本身并不包含在对象的本身大小上面,在对象中保存一个指针,它能够找到动态申请的内存的地址。所以,你不管动态申请多少内存,它对象中的一个指针总能找得到你,它指针的大小不会发生改变。也就是说,它所在的结构体变量的大小也是不会改变的!

      我也写了一个小程序检查了一下,大家可以通过运行结果看到结构体变量的大小并没有改变!

#include <iostream>
#include <string>
#include <vector>
 
using namespace std;
 
typedef struct Vec
{
	vector<int> int_vec;
}Int_vec;
 
typedef struct Str
{
	string str;
}Str_string;
 
int main(void)
{
 
	Int_vec myInt;
	Str_string myString;
 
	cout << "空的 myInt 大小:" << sizeof(myInt) << endl << endl;
	cout << "空的 myString 大小:" << sizeof(myString) << endl << endl;
	
	
	for (int i = 0; i < 10;i++)
	{
		myInt.int_vec.push_back(i);
	}
 
	myString.str = "student";
	cout << "有十个元素的 myInt 大小:" << sizeof(myInt) << endl << endl;
	cout << "有字符串内容的 myString 大小:" << sizeof(myString) << endl << endl;
 
	return 0;
}

原文:https://www.freesion.com/article/4349729055/

### 3.1 可变参数模板的基本语法 C++11 引入了可变参数模板(Variadic Templates),允许定义接受不定数量和类型参数的模板[^2]。其基本语法如下: ```cpp template <typename... Args> void func(Args... args) { // 函数体 } ``` 其中,`Args...` 是一个模板参数包(template parameter pack),表示可以接受任意数量的类型参数;`args` 是函数参数包(function parameter pack),表示函数可以接受任意数量和类型的实参。 ### 3.2 参数包的展开方式 可变参数模板的核心在于参数包的展开(parameter pack expansion)。通过递归展开或折叠表达式(fold expressions,C++17 起)等方式,可以在编译期处理参数包中的每个参数。 #### 3.2.1 递归展开 最常见的展开方式是使用递归模板实例化,依次处理每个参数: ```cpp // 基例:无参数 void print() { std::cout << std::endl; } // 递归展开 template <typename T, typename... Args> void print(T first, Args... rest) { std::cout << first << " "; print(rest...); } // 使用示例 print(1, 2.0, "hello"); // 输出: 1 2 hello ``` #### 3.2.2 折叠表达式(C++17) C++17 引入了折叠表达式,可以更简洁地处理参数包中的操作: ```cpp template <typename... Args> auto sum(Args... args) { return (args + ...); // 右折叠 } // 使用示例 int result = sum(1, 2, 3, 4); // result = 10 ``` ### 3.3 可变参数模板的实际应用场景 可变参数模板广泛用于现代 C++ 编程中,特别是在标准库和元编程中。以下是几个典型应用场景: #### 3.3.1 构造函数和 `emplace` 接口 STL 容器如 `std::vector` 和 `std::map` 提供了 `emplace` 系列函数,利用可变参数模板直接在容器内部构造对象,避免不必要的拷贝或移动操作: ```cpp std::vector<std::string> vec; vec.emplace_back("Hello"); // 直接构造 std::string("Hello") ``` #### 3.3.2 函数对象封装(如 `std::function` 和 `std::bind`) `std::function` 和 `std::bind` 利用可变参数模板实现对任意可调用对象的封装,支持不同参数数量和类型的调用: ```cpp std::function<int(int, int)> f = [](int a, int b) { return a + b; }; int result = f(3, 4); // result = 7 ``` #### 3.3.3 编译期类型列表和元编程 可变参数模板常用于模板元编程中,构建类型列表、实现编译期反射、类型检查等: ```cpp template <typename... Types> struct TypeList {}; TypeList<int, double, std::string> list; ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值