Effective STL 学习笔记 Item 16:vector, string & C API
有时需要支持 C 的接口,但这并不复杂。
对于 vector 来讲, \(v[0]\) 的地址 \(\&v[0]\) 即可作为数组指针传递给 C API:
1: // Legacy C API.
2: extern void doSomething(const int* pInts, size_t numInts);
3:
4: vector<int> v;
5: // ...
6: // Operations on v.
7: // ...
8:
9: if (!v.empty())
10: {
11: doSomething(&v[0], v.size());
12: }
也许有人会说:可以用 v.begin() 来替代 \(\&v[0]\), 但并非永远如此, v.begin() 返回的是一个迭,迭代器指向的对象的地址才是真正的 \(\&v[0]\) ,即:
&*v.begin() == &v[0]
String 对象没有要求保证所有字符串都存放在连续的内存空间,而且 string 内部不会保证内存中对象会以 NULL 结尾,上面对 \(\&v[0]\) 的方法对 string 不一定行得通,对 string 来讲,我们应该使用它提供的成员函数: c_str() , 下面的代码中无需检查 ss 是否为空,因为如果 ss 为空, ss.c_str() 会返回 NULL 。
13: // Legacy C API:
14: extern void doSomething(const char* str);
15:
16: string ss;
17: // ...
18: // Do something with ss
19: // ...
20:
21: doSomething(ss.c_str());
注意第 2 和第 14 行中 C API 中的 const 限定符,调用的函数不应该修改指针指向的内容,但如果我们需要通过调用 C API 来初始化 vector 或 string,应该怎么做?
对于 vector 来讲, Item 14 提到,通过 reserve() 可以预留出足够的空间,而且是连续空间,这样我们可以在调用 C API 进行初始化之前来分配好足够空间,并在初始化之后调用 resize() 来改变容器的大小:
// C API: this function takes a pointer to an array of at most arraySize
// doubles and writes data to it. It returns the number of doubles written,
// which is never more than maxNumDoubles.
size_t fillArray(double *pArray, size_t arraySize); vector<double> vd;
vd.reserve(maxNumDoubles);
vd.resize(fillArray(&vd[0], maxNumDoubles))
或者更简单的:
vector<double> vd(maxNumDouble);
vd.resize(fillArray(&vd[0], vd.size()));
String 提供的 c_str() 指向的指针是只读的,不能将其传给 C API 进行初始化,但我们可以通过前面提到的方法:将 vector<char> 的指针传给 C API,然后再用这个 vector 来初始化 string
// C API: this function takes a pointer to an array of at most arraySize
// chars and writes data to it. It returns the number of chars written,
// which is never more than maxNumChars. size_t fillString(char* pArray, size_t arraySize); vector<char> vc(maxNumChars);
size_t charsWritten = fillString(&vc[0], vc.size());
string s(vc.begin(), vc.begin()+charsWritten));
上面的这个技巧,可以适用于任何的容器,例如如果我们想用 C API 来初始化一个 set:
size_t doSomething(int* pints, size_t numInts); // C API to initialize int array.
vector<int> v(maxNumInts); // This is media
size_t sz = doSomething(&v[0], v.size());
set<int> intSet(v.begin(), v.begin()+sz);
(使用许可:署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议 。)
Effective STL 学习笔记 Item 16:vector, string & C API的更多相关文章
- Effective STL 学习笔记: 多用 vector & string
Effective STL 学习笔记: 多用 vector & string 如果可能的话, 尽量避免自己去写动态分配的数组,转而使用 vector 和 string . 原书作者唯一想到的一 ...
- Effective STL 学习笔记 Item 34: 了解哪些算法希望输入有序数据
Effective STL 学习笔记 Item 34: 了解哪些算法希望输入有序数据 */--> div.org-src-container { font-size: 85%; font-fam ...
- Effective STL 学习笔记 Item 30: 保证目标区间足够大
Effective STL 学习笔记 Item 30: 保证目标区间足够大 */--> div.org-src-container { font-size: 85%; font-family: ...
- Effective STL 学习笔记 Item 26: Prefer Iterator to reverse_iterator and const_rever_itertor
Effective STL 学习笔记 Item 26: Prefer Iterator to reverse_iterator and const_rever_itertor */--> div ...
- Effective STL 学习笔记 Item 38 : Design functor classes for pass-by-value
Effective STL 学习笔记 Item 38 : Design functor classes for pass-by-value */--> div.org-src-container ...
- Effective STL 学习笔记 Item 21:Comparison Function 相关
Effective STL 学习笔记 Item 21:Comparison Function 相关 */--> div.org-src-container { font-size: 85%; f ...
- Effective STL 学习笔记 Item 18: 慎用 vector<bool>
vector<bool> 看起来像是一个存放布尔变量的容器,但是其实本身其实并不是一个容器,它里面存放的对象也不是布尔变量,这一点在 GCC 源码中 vector<bool> ...
- Effective STL 学习笔记 Item 17: Swap Trick
假设有若干对象存于一个 vector 中: class Widget; vector<Widget> vw; 后来由于某些原因,从该容器中删除了若干对象(参考erase-remove id ...
- Effective STL 学习笔记: Item 22 ~ 24
Effective STL 学习笔记: Item 22 ~ 24 */--> div.org-src-container { font-size: 85%; font-family: monos ...
随机推荐
- MySQL数据库语法-多表查询练习一
MySQL数据库语法-多表查询练习一 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 本篇博客主要介绍的多表查询的外键约束,以及如何使用外链接和内连接查询数据信息. 一.数据表和测试 ...
- c# 的一些基本操作或属性
http下载文件,不保存到服务器,直接使用浏览器下载 /// <summary> /// 根据url下载文件 /// </summary> /// <param name ...
- css3-自定义字体
参考链接http://www.w3cplus.com/content/css3-font-face 出处W3CPLUS css3-自定义字体 @font-face @font-face是CSS3中 ...
- 最佳的MongoDB客户端管理工具
<最佳的MongoDB客户端管理工具> 作者:chszs,未经博主允许不得转载.经许可的转载需注明作者和博客主页:http://blog.csdn.net/chszs 一个好的MongoD ...
- LintCode 387: Smallest Difference
LintCode 387: Smallest Difference 题目描述 给定两个整数数组(第一个是数组A,第二个是数组B),在数组A中取A[i],数组B中取B[j],A[i]和B[j]两者的差越 ...
- 20155236 2016-2017-2 《Java程序设计》第五周学习总结
20155236 2016-2017-2 <Java程序设计>第五周学习总结 教材学习内容总结 Java的异常处理是通过5个关键字来实现的:try,catch,throw,throws,f ...
- OpenCV3.4.1+vs2017安装及配置
一.OpenCV3.4.1下载与安装 1.OpenCV3.4.1下载 可以去OpenCV官网上下载http://opencv.org/ 然后找到对应的系统环境就可以下载了,当然了官网上下载会很慢,推荐 ...
- 适配器在JavaScript中的体现
适配器设计模式在JavaScript中非常有用,在处理跨浏览器兼容问题.整合多个第三方SDK的调用,都可以看到它的身影. 其实在日常开发中,很多时候会不经意间写出符合某种设计模式的代码,毕竟设计模式就 ...
- vue-cli环境搭建初探!
1.先安装nodejs环境 https://npm.taobao.org/mirrors/node (选择版本) 下一步 下一步 默认安装就行 2.检查node和npm的是否成功安装 node -v ...
- [转]caffe中solver.prototxt参数说明
https://www.cnblogs.com/denny402/p/5074049.html solver算是caffe的核心的核心,它协调着整个模型的运作.caffe程序运行必带的一个参数就是so ...