仿函数(function object,函数对象)

2016/01/12

引子

前一篇文章讲到了C++11的新特性lambda表达式

lambda表达式的本质是什么呢?为探究这个问题,我们将一段写有lambda表达式的代码反编译,可能会发现一些秘密.

首先写段程序:

在调试该代码时我们打开汇编视图,发现如下代码:

其中 <$_0::operator()(int, int) const>      即对应原代码中的lambda表达式。这里一串重载了”()”(operator())操作符的代码,即本文将要了解的仿函数

Note:  此处的 const  ,也应证了前文 mutable 可变范围 中提到的,lambda的调用运算符为”const-by-value”的

  定义

仿函数(finctor)是一种早期的叫法,在C++11中,标准的叫法为函数对象(function object)。仿函数是一种行为类似函数、具有函数特性的对象。

仿函数是一个对象,而不是函数。仿函数的类通过重载函数操作符”()”(operator())来实现函数调用的特性。

通过下面的例子来简单说明如何使用仿函数

这个例子中,lineA声明了一个对象。这是一个函数对象,其类(结构)定义在functional文件中,是STL内置的模板类。该类用于比较两个参数的大小。

lineB则像函数一样直接给该对象传入两个参数。

lineC是另一种写法。greater<int>() 声明了一个临时对象,然后传入参数(3,4)调用该临时对象。这种写法往往比lineB更加简洁。在STL源码里大量使用了这种写法。

lineD则是使用自定义的函数对象。

Note:lineB中使用了boolalpha,是iostream提供的一个操作符,这将使此后的标准输出中,将bool值输出为”true”或”false”,而不是1/0。于其相反的操作为noboolalpha.

阅读全文…

Coding 2,815

lambda 表达式

2016/01/11

LAMBDA简介lambda

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

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

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

此例中,

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

阅读全文…

Coding 3,653

使用 RasterIO 读取影像

2015/06/20

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

 原型

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

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

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 每波段数据元大小 。用参数来表示:

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 开始的。 阅读全文…

Coding 3,153

GitHub 设置代理

2015/06/16

红杏老板带吃喝嫖赌欠下……也不知道多少钱,带着他的小姨子跑了……所以,以下部分不用看了。再见。

 

运营商对GitHub的封锁使很多开发者感到头疼。幸好,我们还有VPN.

本文介绍如何结合红杏VPN公益版使用GitHub 。

红杏和(fān)谐(qiáng),想必大家在和GFW做斗争的时候都已经很熟悉了。做为一款和谐插件,红杏还是比较可靠的,收费也比较便宜。但是有一点比较难以接受的是,它无法给其他软件提供代理。为了弥补这个问题,红杏推出了一个公益版本,给广大开发者提供了一个免费的VPN服务器地址:

http://hx.gy:1080

在此次过程中,我们使用的就是这个地址。

git提供如下命令允许用户配置代理: 阅读全文…

Note 3,721

Sqlite3 写入数据库失败:attempt to write a readonly database.

2015/05/24

问题及解决办法

一个Android程序在大部分手机上运行正常,在某一款手机(华为荣耀7)上运行失败。具体表现为在写入Sqlite数据库时出现Sqlite3Exception :attempt to write a readonly database.

在仔细检查sqlite3_open/sqlite3_open_v2的参数、apk的SD卡读取权限、sqlite数据库的文件读写权限后,并没有发现任何问题,那么分析问题可能出在NDK与机器架构上了。

查看该机器使用的是arm64位CPU.然而在application.mk文件里,APP_ABI 并未配置64位选项。

配置

 APP_ABI   := armeabi-v7a arm64-v8a

后再使用NDK编译 ,解决sqlite3的Readonly的问题。

 

 

Note 3,159

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

2015/05/12

§§ 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

 

阅读全文…

Coding 3,788