lambda 表达式

LAMBDA简介lambda

从C++11开始,c++开始支持lambda表达式。

lambda用来创建一个可以捕获作用域内变量的匿名函数对象的闭包。这通常用来封装传递给算法或异步方法的少量代码块。

例如,简单实现一个Trim函数,去除字符串里的空格:

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

string trimall(string str)
{
    vector<char> vec;
    for_each(str.begin(),str.end(),[&vec](char c){if(!isspace(c)) vec.push_back(c);});
    return string(vec.begin(),vec.end());
}

int main() {
    std::string str = "   Hi, lam b da!";
    
    std::cout << trimall(str);
    
    return 0;
}

//OUTPUT:
//Hi,lambda!

此例中,

[&vec](char c){if(!isspace(c)) vec.push_back(c);}

即是一个lambda表达式。其做为一个匿名函数,被算法  for_each 使用,使得代码更简洁。

阅读更多

使用 RasterIO 读取影像

gdalbaner当我们使用 GDAL  从栅格数据(RasterData)影像中读写数据的时候,我们最常使用的方法就是 RasterIO。 GDAL 在 GDALDataset 类和 GDALRasterBand 类中都提供了 RasterIO 方法。在这两个类中,RasterIO 函数的差别不大。下面我们通过一个实例来具体了解如何使用 RasterIO

 原型

在 GDALDataset 中,RasterIO  方法的定义如下:

CPLErr GDALDataset::RasterIO(GDALRWFlag         eRWFlag,
	int     nXOff,
	int     nYOff,
	int     nXSize,
	int     nYSize,
	void *  pData,
	int     nBufXSize,
	int     nBufYSize,
	GDALDataType    eBufType,
	int     nBandCount,
	int *   panBandMap,
	int     nPixelSpace,
	int     nLineSpace,
	int     nBandSpace
)

下面我们来了解各个参数的意义:

eRWFlag
它用来指示 RasterIO 的操作方式,读,还是写。GDALRWFlag 枚举有两个值, GF_Read = 0 为读取数据, GF_Write = 1  为写数据。

nXOff,nYOff
它用来指示 RasterIO 在影像上操作(读或写)范围的起始坐标。在影像中,左上角的坐标为 (0,0)。

nXSize,nYSize
它用来指示 RasterIO 在影像上操作范围的大小。nXSize为宽,nYSize为高。 它以 (nXOff,nYOff)为起点,决定了操作影像的范围的大小。

pData
这是一个指针,指向缓存数据块。如果 eRWFlag 为 GF_Write,函数会将 pData 中的数据写入影像,如果为 GF_Read, 那么函数会将从影像中取得的数据写入到 pData 中。 pData 为 void* 类型,它真实的数据类型将由参数 eBufType 决定。
由于 pData 为 void* 类型,所以它的大小一般使用 字节(byte) 来作单位。它的大小需要最底满足缓冲区的大小。即 缓冲区内存块大小 = 缓冲区长 X 缓冲区宽 X 波段数 X 每波段数据元大小 。用参数来表示:

//GDALGetDataTypeSize返回数据类型所占位数,故需要除以 8 
int nDataSize = nBufXSize * nBufYSize * nBandCount * GDALGetDataTypeSize(eBufType) / 8

nBufXSize,nBufYSize
它用来指定缓冲区的宽高。这两个参数配合 nXSize,nYSize 来实现对影像的缩放。例如,如果 nBufXSize > nXSize,即缓存区宽度比影像操作区宽度大,那么读取数据时,将得到一个在 X 方向放大的缓冲数据。反之则得到缩小的缓冲数据。
值得注意的是,在读取并缩小影像时,GDAL 将自动分析金字塔(Overviews)中数据,选取合适的金字塔层来来读取数据。所以建立合适的金字塔,对读取影像的效率的很大帮助。

eBufType
它也是一个枚举,用来指示操作的数据类型。如果它与 GDALRasterBand 的数据类型不一致,则 RasterIO 将会做类型转换。需要注意的是,将数据从较大的单位向较小的单位进行转换时,RasterIO 会将数据截取而不是比例缩小。例如从 GDT_Int16(Thirty two bit unsigned integer)转为 GDT_Byte(Eight bit unsigned integer)时,超出 255 的部分将会被直接丢弃。

nBandCount,panBandMap
nBandCount为要操作的波段数。panBandMap则为读写的波段的顺序,即我们可以先读取哪一个波段,后读取哪一个波段。它是一个 int 型数组,内容为波段编号,大小为 nBandCount。这个参数可以为 NULL,这样将默认顺序使用影像的前 nBandCount 个波段来读写。需要注意的是,波段编号是从 1 开始的。

阅读更多

树莓派 + DHT11 获取温度与湿度

§§ DHT11介绍

DHT11是一款含有已校准数字信号输出的温湿度复合传感器。包括一个电阻式感湿元件和一个NTC测温元件,可与8位单片机相连接。是一款广泛使用是电子元器件。DHT11的一般形态如下图:

DHT11采用四PIN引bKKNC脚。

  • 引脚1:VCC.  接入3~5.5V直流电源。
  • 引脚2:Data.  串行数据总线
  • 引脚3:N/A.  空引脚
  • 引脚4:GND.  接地线

DHT11的供电电压为 3-5.5V。传感器上电后,要等待 1s 以越过不稳定状态.电源引脚(VDD,GND)之间可增加一个100nF 的电容,用以去耦滤波。

串行数据总线用于和单片机进行数据通讯和同步。一次通信时间在4ms左右,传输40bit数据,高位先出。数据协议8位为一组,由高至底分别为:

  • 8bit  湿度整数部分
  • 8bit  湿度小数部分
  • 8bit  温度整数部分
  • 8bit  温度小数部分
  • 8bit  检验和

dht11_data

 

阅读更多

使用hashlib++进行hash/md5加密

最近一个跨平台项目中要用到MD5算法。立马想到了大名鼎鼎的Cryptopp(Cryto++)。CryptoPP功能强大且应用非常广泛,实现了众多加密算法,被很多项目使用,如OpenSSL。于是从Cryptopp的主页下载的源码进行编译。在Windows上编译为DLL一切良好,但在Mac上为IOS编译后,发现其编译的静态库体积太过庞大,单个平台上库的体积超过20M.在多平台交叉编译,尽管使用Oz优化,.a文件仍超过了100M。因为其大量使用了模板,代码膨胀极其恐怖。这个体积给项目协作带来极大不便。所有对CryptoPP库只好忍痛放弃。

只好转向另一个实现Hash算法的库Hashlib++.该库是一个简单便捷的hash加密算法库。用其官网的话说,就是"simple and very easy to use library to create a cryptographic checksum called "hash" in C++"。

其源码在此处下载!

§§ 编译

  • 在Windows下编译:

VS新建空项目,然后加入所有源码,即可使用。但如果要编译成动态库时,就需要对源码进行改动,因为源码没有提供函数导出符号。在需要导出的类前添加 __declspec(dllexport) 修饰即可导出相应的类。

  • 在Mac下编译(for IOS):

阅读更多

Linton法则

当我们在实现一个带有引用参数的函数时,可能会将该参数的地址存储在该函数作用域外的某个地方。如下代码所示: My ... 阅读更多