有时需要支持 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);

Effective STL 学习笔记 Item 16:vector, string & C API的更多相关文章

  1. Effective STL 学习笔记: 多用 vector & string

    Effective STL 学习笔记: 多用 vector & string 如果可能的话, 尽量避免自己去写动态分配的数组,转而使用 vector 和 string . 原书作者唯一想到的一 ...

  2. Effective STL 学习笔记 Item 34: 了解哪些算法希望输入有序数据

    Effective STL 学习笔记 Item 34: 了解哪些算法希望输入有序数据 */--> div.org-src-container { font-size: 85%; font-fam ...

  3. Effective STL 学习笔记 Item 30: 保证目标区间足够大

    Effective STL 学习笔记 Item 30: 保证目标区间足够大 */--> div.org-src-container { font-size: 85%; font-family: ...

  4. 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 ...

  5. 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 ...

  6. Effective STL 学习笔记 Item 21:Comparison Function 相关

    Effective STL 学习笔记 Item 21:Comparison Function 相关 */--> div.org-src-container { font-size: 85%; f ...

  7. Effective STL 学习笔记 Item 18: 慎用 vector<bool>

    vector<bool> 看起来像是一个存放布尔变量的容器,但是其实本身其实并不是一个容器,它里面存放的对象也不是布尔变量,这一点在 GCC 源码中 vector<bool> ...

  8. Effective STL 学习笔记 Item 17: Swap Trick

    假设有若干对象存于一个 vector 中: class Widget; vector<Widget> vw; 后来由于某些原因,从该容器中删除了若干对象(参考erase-remove id ...

  9. Effective STL 学习笔记: Item 22 ~ 24

    Effective STL 学习笔记: Item 22 ~ 24 */--> div.org-src-container { font-size: 85%; font-family: monos ...

随机推荐

  1. Razor:从aspx到cshtml常见错误及正确书写方法

    http://blog.csdn.net/cheny_com/article/details/6298496 从aspx转到chshtml还是有很多要适应的地方的,本帖是个人学习笔记帖不断更新.每天开 ...

  2. mysql 5.7 json 字段类型查找、修改

    修改 json 里的数组字段 mysql> set @json = '{"test": [{"name": "laravel"}, { ...

  3. C++中的空类,编译器默认可以产生哪些成员函数

    C++中的空类,编译器默认可以产生哪些成员函数 C++中创建一个空类:class Empty {};默认会生成4个函数,其函数的原型如下: public: Empty() { ... } Empty( ...

  4. NO.1 Day 计算机基础

    计算机基础 1.编程语言的作用及与操作系统和硬件的关系 编程语言是程序员与计算机之间沟通的媒介. 一套完整的计算机系统分为计算机硬件.操作系统和软件三部分.编程语言开发的结果为软件.软件的运行在操作系 ...

  5. koa中间件机制

    Koa是Express原班人马打造的一个更小,基于nodejs平台的下一代web开发框架. koa2利用的是async/await,洋葱圈模型. 1. koa2中间件基本用法

  6. 如何使用vuejs过滤器

    大家再使用vue做项目时,查询功能当然必不可少,这就得使用vue强大的filter啦.其实vue内置的两个属性filterBy和orderBy已经能满足部分需求了,但是她更大的的魅力在于自定义filt ...

  7. java抽象类和普通类的区别

    1.抽象类不能被实例化. 2.抽象类可以有构造函数,被继承时子类必须继承父类一个构造方法,抽象方法不能被声明为静态. 3.抽象方法只需申明,而无需实现,抽象类中可以允许普通方法有主体 4.含有抽象方法 ...

  8. sparse representation 与sparse coding 的区别的观点

    @G_Auss: 一直觉得以稀疏为目标的无监督学习没有道理.稀疏表示是生物神经系统的一个特性,但它究竟只是神经系统完成任务的副产物,还是一个优化目标,没有相关理论,这里有推理漏洞.实际上,稀疏目标只能 ...

  9. Spring Boot 集成 MyBatis和 SQL Server实践

    概 述 Spring Boot工程集成 MyBatis来实现 MySQL访问的示例我们见过很多,而最近用到了微软的 SQL Server数据库,于是本文则给出一个完整的 Spring Boot + M ...

  10. phpcm nginx 伪静态文件

    rewrite ^/show-([0-9]+)-([0-9]+)-([0-9]+).html /index.php?m=content&c=index&a=show&catid ...