Tuesday, 28 February 2017

xargs 命令行参数转换



xargs 能够将输入数据转化为特定命令的命令行参数;这样,可以配合很多命令来组合使用。比如grep,比如find;

  • 将多行输出转化为单行输出
cat file.txt| xargs
\n 是多行文本间的定界符

  • 将单行转化为多行输出
cat single.txt | xargs -n 3
-n:指定每行显示的字段数

xargs参数说明

-d 定义定界符 (默认为空格 多行的定界符为 \n)
-n 指定输出为多行
-I {} 指定替换字符串,这个字符串在xargs扩展时会被替换掉,用于待执行的命令需要多个参数时
eg:

cat file.txt | xargs -I {} ./command.sh -p {} -1

-0:指定\0为输入定界符
eg:统计程序行数

find source_dir/ -type f -name "*.cpp" -print0 |xargs -0 wc -l

Monday, 27 February 2017

grep 文本搜索



grep match_patten file // 默认访问匹配行

  • 常用参数
-o 只输出匹配的文本行 VS -v 只输出没有匹配的文本行
-c 统计文件中包含文本的次数

  grep -c "text" filename

-n 打印匹配的行号
-i 搜索时忽略大小写
-l 只打印文件名

  • 在多级目录中对文本递归搜索(程序员搜代码的最爱):

  grep "class" . -Rn
or
          grep "class" -rn  

  • 匹配多个模式

  grep -e "class" -e "vitural" file

Sunday, 26 February 2017

How to grep in a certain kind of file?

Use the --include optoin, E.g. just grep in header file (*.h) and source file (*.cpp)
 
grep -rn --include \*.h --include \*.cpp 'word_to_grep'  dst/directory/

Saturday, 25 February 2017

llvm SDValue

00091 /// Unlike LLVM values, Selection DAG nodes may return multiple
00092 /// values as the result of a computation.  Many nodes return multiple values,
00093 /// from loads (which define a token and a return value) to ADDC (which returns
00094 /// a result and a carry value), to calls (which may return an arbitrary number
00095 /// of values).
00096 ///
00097 /// As such, each use of a SelectionDAG computation must indicate the node that
00098 /// computes it as well as which return value to use from that node.  This pair
00099 /// of information is represented with the SDValue value type.
00100 ///
00101 class SDValue {
00102   friend struct DenseMapInfo<SDValue>;
00103 
00104   SDNode *Node;       // The node defining the value we are using.
00105   unsigned ResNo;     // Which return value of the node we are using.
00106 public:
00107   SDValue() : Node(nullptr), ResNo(0) {}
00108   SDValue(SDNode *node, unsigned resno);
00109 
00110   /// get the index which selects a specific result in the SDNode
00111   unsigned getResNo() const { return ResNo; }
 
 
Note, by default the result value is in the the first one,  cause we have  the default
set "ResNo(0)", knowing this is  very important for handling hardware instruction that
has multiple outputs which cannot be handled in .td file (like ADDC, SUBFC ADDIC etc) 

find 文件查找 (advanced)



  • 查找txt和pdf文件
  find . \( -name "*.txt" -o -name "*.pdf" \) -print

  • 否定参数
       查找所有非txt文本 (!)

   find . ! -name "*.txt" -print

  • 指定搜索深度
       打印出当前目录的文件(深度为1)

  find . -maxdepth 1 -type f 


定制搜索

  • 按类型搜索:
  find . -type d -print  //只列出所有目录, 这里的d是directory的意思
-type f 文件 / l 符号链接


  • 按时间搜索: (Does not work for me, need to figure out why)

-atime 访问时间 (单位是天,分钟单位则是-amin,以下类似)
-mtime 修改时间 (内容被修改)
-ctime 变化时间 (元数据或权限变化)


  • 最近7天被访问过的所有文件:

 find . -atime 7 -type f -print

  • 按大小搜索:
       w字 k M G
       寻找大于2k的文件


找到后的后续动作

  • 删除:
删除当前目录下所有的swp文件: (这个对常用vim的同学非常有用)

  find . -type f -name "*.swp" -delete



forwarded from:

http://mp.weixin.qq.com/s?__biz=MzAxODI5ODMwOA==&mid=2666540479&idx=2&sn=3d31b275c840f07aacbe27c8c0f80145&chksm=80dce914b7ab6002d72ba8cdd724e7d5dcb967313301846dff5f1554d20c382794fe62fd0659&mpshare=1&scene=5&srcid=0225JX3GZ2o4co9AOHf5rJyG#rd

Thursday, 23 February 2017

How to grep a specific pattern?

Like if I want to grep (outs 1_or_more_any_number_or_letter  : 1_or_more_any_number_or_letter  in lib/Target folder, I can do the following:

grep -Rl '(outs [a-zA-Z0-9][a-zA-Z0-9]*:\$[a-zA-Z0-9][a-zA-Z0-9]*,' lib/Target/


note here option -l (lower case L), meaning:

 -l, --files-with-matches
              Suppress normal output; instead print the name of each input file from which output would normally have been printed.
              The scanning will stop on the first match.  (-l is specified by POSIX.)

Wednesday, 22 February 2017

19. How to apply a patch?


patch < ~/patches/vec_xl_xst.diff
If the patch cannot be applied automatically, then paste the file name to apply patch to each file.

You need to specify -p1 to apply the patch without asking you to confirm ( sometimes you need p0,
depending on where you create and apply the patch)
patch -t -p1 < ~/patches/expand.comparison

Tuesday, 21 February 2017

Load Word and Zero with Update (LWZU/lwzu) D-form


lwzu RT,D(RA)

33 RT RA D
0 6 11 16 31

EA <--  (RA) + EXTS(D)
RT <-- 320 || MEM(EA, 4)
RA <-- EA

Let the effective address (EA) be the sum (RA)+ D. The
word in storage addressed by EA is loaded into
RT32:63. RT0:31 are set to 0.
EA is placed into register RA.
If RA=0 or RA=RT, the instruction form is invalid.
Special Registers

Sunday, 19 February 2017

Branch I-form


b target_addr (AA=0 LK=0)
ba target_addr (AA=1 LK=0)
bl target_addr (AA=0 LK=1)   
bla target_addr (AA=1 LK=1)

if AA then NIA <-- iea EXTS(LI || 0b00)
else NIA <-- iea CIA + EXTS(LI || 0b00)
if LK then LR <--iea CIA + 4

target_addr specifies the branch target address.

If AA=0 then the branch target address is the sum of
LI || 0b00 sign-extended and the address of this
instruction
, with the high-order 32 bits of the branch target
address set to 0 in 32-bit mode.

If AA=1 then the branch target address is the value
LI || 0b00 sign-extended, with the high-order 32 bits of
the branch target address set to 0 in 32-bit mode.

If LK=1 then the effective address of the instruction following
the Branch instruction is placed into the Link
Register.

 
Special Registers Altered:
LR (if LK=1)

Note:  bl ADDRESS usually used to do subroutine call to address ADDRESS

NOR (NOT OR)

NOR X-form
nor RA,RS,RB (Rc=0)
nor. RA,RS,RB (Rc=1)

RA <-  ¬((RS) | (RB))
The contents of register RS are ORed with the contents
of register RB and the complemented result is placed
into register RA.

Special Registers Altered:
CR0 (if Rc=1)

Extended Mnemonics:
Example of extended mnemonics for NOR

Extended: Equivalent to:
NOT Rx,Ry   <=> NOR Rx,Ry,Ry


Please  NOTE here there is no logical NOT instruction on PPC architecture. Instead, we have this alias of nor Rx, Ry, Ry, which is actually equivalent to NOT Rx, Ry. But physically, there is no NOT hard instruction on PPC architecture, just NOR.
 

LD/LBZ/LHZ/LWZ (ld/lbz/lhz/lwz)

LD/ld: Load Doubleword DS-form:

ld REGA, 0(REGB)

    use the contents of REGB as the memory address of the value to load into REGA


LBZ/lbz:  Load Byte and Zero  D-form:
LHZ/lhz:  Load Half Land Zero  D-form,
LWZ/lwz: Load Word and Zero D-form

    all of these follow the same format, but operate on bytes, halfwords, and words, respectively (the "z" indicates that they also zero-out the rest of the register)

Friday, 17 February 2017

19. Population Count Doubleword X-form (popcntd/POPCNTD)


popcntd RA, RS

31 RS RA /// 506 Rc
0  6  11 16  21  31

n <- 0
do i = 0 to 63
if (RS)i = 1 then
n <- n+1
RA <- n

A count of the number of one bits in register RS is
placed into register RA. This number ranges from 0 to
64, inclusive.

Special Registers Altered:
None

18. Extend Sign Word X-form (extsw/EXTSW)


extsw RA,RS (Rc=0)
extsw. RA,RS (Rc=1)

31 RS RA /// 986 Rc
0  6  11 16  21  31

s <- (RS)32
RA32:63 <- (RS)32:63
RA0:31 <- 32s
(RS)32:63 are placed into RA32:63. RA0:31 are filled with
a copy of (RS)32.

Special Registers Altered:
CR0 (if Rc=1)




AIX 6.1:  

extsw (Extend Sign Word) instruction

Purpose
Copy the low-order 32 bits of a general purpose register into another general purpose register, and sign extend the fullword to a doubleword in size (64 bits).
Syntax
Bits Value
0-5 31
6-10 S
11-15 A
16-20 00000
21-30 986
31 Rc
PowerPC®
extsw RA, RS (Rc=0)
extsw. RA, RS(Rc=1)
Description
The contents of the low-order 32 bits of general purpose register (GPR) RS are placed into the low-order 32 bits of GPR RA. Bit 32 of GPR RS is used to fill the high-order 32 bits of GPR RA.
Other registers altered:
  • Condition Register (CR0 field):
    Affected: LT, GT, EQ, SO (if Rc = 1)
  • XER:
    Affected: CA
Parameters
Item Description
RA Specifies the target general purpose register for the result of the operation.
RS Specifies the source general purpose register for the operand of instruction.
Implementation
This instruction is defined only for 64-bit implementations. Using it on a 32-bit implementation will cause the system illegal instruction error handler to be invoked.

Thursday, 16 February 2017

17. XER (Fixed-Point Exception Register)


3.2.2 Fixed-Point Exception
Register
The Fixed-Point Exception Register (XER) is a 64-bit
register.

The bit definitions for the Fixed-Point Exception Register
are shown below. Here M=0 in 64-bit mode and
M=32 in 32-bit mode.

The bits are set based on the operation of an instruction
considered as a whole, not on intermediate results
(e.g., the Subtract From Carrying instruction, the result
of which is specified as the sum of three values, sets
bits in the Fixed-Point Exception Register based on the
entire operation, not on an intermediate sum).

Bit(s Description:

0:31 Reserved

32: Summary Overflow (SO)
is set to 1 whenever an instruction (except mtspr) sets the Overflow bit.

33: Overflow (OV)
The Overflow bit is set to indicate that an overflow has occurred during execution of an instruction

34: Carry (CA)
ADDC,SUBFC, ADDE, SUBFE set it to 1 if there is a bit carry out of bit M
SRA* set it to 1 if any 1-bits have been shifted out of a negative operand

35:43 Reserved

44: Overflow32 (OV32)

V32 is set whenever OV is set

45: Carry32 (CA32)
CA32 is set whenever CA is set

46:56 Reserved

57:63 This field specifies the number of bytes to be
transferred by a Load String Indexed or Store
String Indexed instruction.

Wednesday, 15 February 2017

16. Extend Sign Byte X-form (extsb/EXTSB)

The meaning of this PPC hardware instruction is obvious: copy the byte from source register to destination register and extend the signed bit of the byte to the remaining 56 bits ( bit0-bit55).

extsb RA,RS (Rc=0)
extsb. RA,RS (Rc=1)
s <- (RS)56
RA56:63 <- (RS)56:63
RA0:55 <- 56s

(RS)56:63 are placed into RA56:63.
RA0:55 are filled with
a copy of (RS)56.

Special Registers Altered:
CR0 (if Rc=1)

Tuesday, 14 February 2017

15. Subtract From Zero Extended XO-form (subfze/SUBFZE)


subfze RT,RA (OE=0 Rc=0)
subfze. RT,RA (OE=0 Rc=1)
subfzeo RT,RA (OE=1 Rc=0)
subfzeo. RT,RA (OE=1 Rc=1)

31 RT RA /// OE 200 Rc
0  6  11 16  21 22  31

RT  ¬(RA) + CA
The sum ¬(RA) + CA is placed into register RT.
Special Registers Altered:
CA CA32
CR0 (if Rc=1)
SO OV OV32 (if OE=1)

Monday, 13 February 2017

Code Generation Options


-O0, -O1, -O2, -O3, -Ofast, -Os, -Oz, -Og, -O, -O4
Specify which optimization level to use:
-O0 Means “no optimization”: this level compiles the fastest and generates the most debuggable code.
-O1 Somewhere between -O0 and -O2.
-O2 Moderate level of optimization which enables most optimizations.
-O3 Like -O2, except that it enables optimizations that take longer to perform or that may generate larger code (in an attempt to make the program run faster).
-Ofast Enables all the optimizations from -O3 along with other aggressive optimizations that may violate strict compliance with language standards.
-Os Like -O2 with extra optimizations to reduce code size.
-Oz Like -Os (and thus -O2), but reduces code size further.
-Og Like -O1. In future versions, this option might disable different optimizations in order to improve debuggability.
-O Equivalent to -O2.
-O4 and higher
Currently equivalent to -O3

Friday, 10 February 2017

14. Subtract From (subf): XO-form


subf RT,RA,RB (OE=0 Rc=0)
subf. RT,RA,RB (OE=0 Rc=1)
subfo RT,RA,RB (OE=1 Rc=0)
subfo. RT,RA,RB (OE=1 Rc=1)

31 RT RA RB OE 40 Rc
0  6  11 16 21 22 31

RT  ¬(RA) + (RB) + 1
The sum ¬(RA) + (RB) +1 is placed into register RT.
Special Registers Altered:
CR0 (if Rc=1)
SO OV (if OE=1)
Extended Mnemonics:
Example of extended mnemonics for Subtract From:
Extended: Equivalent to:
sub Rx,Ry,Rz subf Rx,Rz,Ry

Thursday, 9 February 2017

13. Subtract From Carrying XO-form (subfc)


subfc RT,RA,RB (OE=0 Rc=0)
subfc. RT,RA,RB (OE=0 Rc=1)
subfco RT,RA,RB (OE=1 Rc=0)
subfco. RT,RA,RB (OE=1 Rc=1)

31 RT RA RB OE 8 Rc
0 6 11 16 21 22 31

RT <-  ¬(RA) + (RB) + 1
The sum ¬(RA) + (RB) + 1 is placed into register RT.
Special Registers Altered:
CA
CR0 (if Rc=1)
SO OV (if OE=1)
Extended Mnemonics:
Example of extended mnemonics for Subtract From
Carrying:

Extended: Equivalent to:
subc Rx,Ry,Rz subfc Rx,Rz,Ry


Wednesday, 8 February 2017

12. Rotate Left Doubleword Immediate then Clear Left MD-form

rldicl RA,RS,SH,MB (Rc=0)
rldicl. RA,RS,SH,MB (Rc=1)
30 RS RA sh mb 0  sh Rc
0  6  11 16 21 27 30 31

The contents of register RS are rotated64 left SH bits. A
mask is generated having 1-bits from bit MB through bit
63 and 0-bits elsewhere. The rotated data are ANDed
with the generated mask and the result is placed into
register RA.
Special Registers Altered:
CR0 (if Rc=1)
Extended Mnemonics:
Examples of extended mnemonics for Rotate Left Doubleword
Immediate then Clear Left

Extended: Equivalent to:
srdi Rx,Ry,n rldicl Rx,Ry,64-n,n

NOTE:
 left shif n bit <=> right shift (64-n) bit in rotate64 mode
 left shif n bit <=> right shift (32-n) bit in rotate32 mode

Tuesday, 7 February 2017

crxor/crand/crnand/crnor/creqv/crandc

7. Condition Register XOR XL-form
crxor BT,BA,BB
19 BT BA BB 449 /
0  6  11 16 193 31

CRBT+32 <-  CRBA+32 XOR CRBB+32

The bit in the Condition Register specified by BA+32 is
XORed with the bit in the Condition Register specified
by BB+32, and the result is placed into the bit in the
Condition Register specified by BT+32.

Special Registers Altered:
CRBT+32

Extended Mnemonics:
Example of extended mnemonics for Condition Register
XOR:
Extended:     Equivalent to:
crclr Bx      crxor Bx,Bx,Bx


8. Condition Register AND XL-form
crand BT,BA,BB
19 BT BA BB 257 /
0  6  11 16 21 31
CRBT+32 <- CRBA+32 & CRBB+32
The bit in the Condition Register specified by BA+32 is
ANDed with the bit in the Condition Register specified
by BB+32, and the result is placed into the bit in the
Condition Register specified by BT+32.
Special Registers Altered:
CRBT+32


9. Condition Register NAND XL-form
crnand BT,BA,BB
19 BT BA BB 225 /
0  6 11 16 21 31
CRBT+32 <-  ¬(CRBA+32 & CRBB+32)
The bit in the Condition Register specified by BA+32 is
ANDed with the bit in the Condition Register specified
by BB+32, and the complemented result is placed into
the bit in the Condition Register specified by BT+32.
Special Registers Altered:
CRBT+32


10. Condition Register NOR
crnor BT,BA,BB
CRBT+32 <- ¬(CRBA+32 | CRBB+32)

Extended        Equivalent to:
crnot Bx,By <=> crnor Bx,By,By



11. Condition Register Equivalent XL-form
creqv BT,BA,BB
19 BT BA BB 289 /
0 6 11 16 21 31

CRBT+32 <- CRBA+32 ≡ CRBB+32
The bit in the Condition Register specified by BA+32 is
XORed with the bit in the Condition Register specified
by BB+32, and the complemented result is placed into
the bit in the Condition Register specified by BT+32.
Special Registers Altered:
CRBT+32

Equivalent:
Extended:    Equivalent to:
crset Bx <=> creqv Bx,Bx,Bx  #set Bx + 32 bit to 1


12.Condition Register AND with Complement
XL-form
crandc BT,BA,BB
19 BT BA BB 129 /
0  6  11 16 21 31
CRBT+32 <- CRBA+32 & ¬CRBB+32
The bit in the Condition Register specified by BA+32 is
ANDed with the complement of the bit in the Condition
Register specified by BB+32, and the result is placed
into the bit in the Condition Register specified by
BT+32.
Special Registers Altered:
CRBT+32

Monday, 6 February 2017

6. Condition Register OR XL-form

cror BT,BA,BB
CRBT+32 <-  CRBA+32 | CRBB+32
The bit in the Condition Register specified by BA+32 is
ORed with the bit in the Condition Register specified by
BB+32, and the result is placed into the bit in the Condition
Register specified by BT+32.

Special Registers Altered:
CRBT+32

Extended Mnemonics:
Example of extended mnemonics for Condition Register
OR:
Extended: Equivalent to:
crmove Bx,By cror Bx,By,By

Sunday, 5 February 2017

ANDC (andc): AND with Complement X-form

5. AND with Complement X-form
andc RA,RS,RB (Rc=0)
andc. RA,RS,RB (Rc=1)
RA <- (RS) & ¬(RB)
The contents of register RS are ANDed with the complement
of the contents of register RB and the result is
placed into register RA.
Special Registers Altered:
CR0 (if Rc=1)





Examples:

    The following code logically ANDs the contents of GPR 4 with the complement of the contents of GPR 5 and stores the result in GPR 6:

    # Assume GPR 4 contains 0x9000 3000.
    # Assume GPR 5 contains 0xFFFF FFFF.
    # The complement of 0xFFFF FFFF becomes 0x0000 0000.
    andc 6,4,5
    # GPR 6 now contains 0x0000 0000.

    The following code logically ANDs the contents of GPR 4 with the complement of the contents of GPR 5, stores the result in GPR 6, and sets Condition Register Field 0 to reflect the result of the operation:

    # Assume GPR 4 contains 0xB004 3000.
    # Assume GPR 5 contains 0x7676 7676.
    # The complement of 0x7676 7676 is 0x8989 8989.
    andc. 6,4,5
    # GPR 6 now contains 0x8000 0000.

RLWINM: Rotate Left Word Immediate then AND with Mask M-form

4. Rotate Left Word Immediate then AND with Mask M-form
rlwinm RA,RS,SH,MB,ME (Rc=0)
rlwinm. RA,RS,SH,MB,ME (Rc=1)
n <- SH
r <- ROTL32((RS)32:63, n)
m <- MASK(MB+32, ME+32)
RA <- r & m
The contents of register RS are rotated32 left SH bits. A mask is generated having 1-bits from bit MB+32 through bit ME+32 and 0-bits elsewhere. The rotated data are ANDed with the generated mask and the result is placed into register RA.

Special Registers Altered:
CR0 (if Rc=1)

Extended Mnemonics:
Examples of extended mnemonics for Rotate Left Word
Immediate then AND with Mask:
21 RS RA SH MB ME Rc
0   6    11   16  21   26  31
Extended: Equivalent to:

extlwi Rx,Ry,n,b rlwinm Rx,Ry,b,0,n-1
srwi Rx,Ry,n rlwinm Rx,Ry,32-n,n,31
clrrwi Rx,Ry,n rlwinm Rx,Ry,0,0,31-n


Programming Note:
This Instruction has many usages, the only one that I have verified so far is:
It can be used to shift the contents of the low-order 32 bits of a register right by n bits, by setting
SH=32-n, MB=n, and ME=31.
If just want the one bit (i1) after shifting, you can set SH=32-n, MB=31, and ME=31

Equivalence verified:
srwi Rx,Ry,n  <=> rlwinm Rx,Ry,32-n,n,31


Example:
jtony@genoa:~/scrum/s8$ cat asm.c
#include <stdio.h>

#define rlwinm( output, input, sh, mb, me ) \
   __asm__( "rlwinm %0, %1, %2, %3, %4" \
          : "=r"(output) \
          : "r"(input), "i"(sh), "i"(mb), "i"(me) \
          : )

int main()
{
   long x = 0x11223344556677A8L ;
   long y ;

   rlwinm( y, x, 27, 31, 31 ) ;

   printf("0x%016lX -> 0x%016lX\n", x, y ) ;

   return 0 ;

}

jtony@genoa:~/scrum/s8$ gcc asm.c ; ./a.out
0x11223344556677A8 -> 0x0000000000000001

Saturday, 4 February 2017

get only the option value in shell script option

What does i#*= mean in the following shell script snippet?

case $i in
        --flags=*)
            FLAGS="$FLAGS${i#*=} "


Here it means attach  the part after symbol '=' of $i to FLAGS.

For example, Let us assume $i is --flags=BBB  if originally FLAGS='AAA ' before executing this line,  after execution, it would become   FLAGS='AAA BBB '

Thursday, 2 February 2017

C++11 新特性:Lambda 表达式


C++11 新特性:Lambda 表达式



或许,Lambda 表达式算得上是 C++ 11 新增特性中最激动人心的一个。这个全新的特性听起来很深奥,但却是很多其他语言早已提供(比如 C#)或者即将提供(比如 Java)的。简而言之,Lambda 表达式就是用于创建匿名函数的。GCC 4.5.x 和 Microsoft Visual Studio 早已提供了对 lambda 表达式的支持。在 GCC 4.7 中,默认是不开启 C++ 11 特性的,需要添加  -std=c++11 编译参数。而 VS2010 则默认开启。
为什么说 lambda 表达式如此激动人心呢?举一个例子。标准 C++ 库中有一个常用算法的库,其中提供了很多算法函数,比如 sort() 和 find()。这些函数通常需要提供一个“谓词函数 predicate function”。所谓谓词函数,就是进行一个操作用的临时函数。比如 find() 需要一个谓词,用于查找元素满足的条件;能够满足谓词函数的元素才会被查找出来。这样的谓词函数,使用临时的匿名函数,既可以减少函数数量,又会让代码变得清晰易读。
下面来看一个例子:
#include <algorithm>
#include <cmath>

void abssort(float *x, unsigned N)
{
  std::sort(x,
            x + N,
            [](float a, float b) { return std::abs(a) < std::abs(b); });
}
下面,我们来详细解释下这个神奇的语法到底代表着什么。
我们从另外一个例子开始:
输出值是什么?3.5!注意,这是一个函数对象(由 lambda 表达式生成),其实参是 -3.5,返回值是参数的绝对值。lambda 表达式的返回值类型是语言自动推断的,因为std::abs()的返回值就是 float。注意,前面我们也提到了,只有当 lambda 表达式中的语句“足够简单”,才能自动推断返回值类型。
C++ 11 的这种语法,其实就是匿名函数声明之后马上调用(否则的话,如果这个匿名函数既不调用,又不作为闭包传递给其它函数,那么这个匿名函数就没有什么用处)。如果你觉得奇怪,那么来看看 JavaScript 的这种写法:
C++ 11 的写法完全类似 JavaScript 的语法。
如果我不想让 lambda 表达式自动推断类型,或者是 lambda 表达式的内容很复杂,不能自动推断怎么办?比如,std::abs(float)的返回值是 float,我想把它强制转型为 int。那么,此时,我们就必须显式指定 lambda 表达式返回值的类型:
这个语句与前面的不同之处在于,lambda 表达式的返回时不是 float 而是 int。也就是说,上面语句的输出值是 3。返回值类型的概念同普通的函数返回值类型是完全一样的。
当我们想引用一个 lambda 表达式时,我们可以使用auto关键字,例如:
auto关键字实际会将 lambda 表达式转换成一种类似于std::function的内部类型(但并不是std::function类型,虽然与std::function“兼容”)。所以,我们也可以这么写:
如果你对std::function<int()>这种写法感到很神奇,可以查看 C++ 11 的有关std::function的用法。简单来说,std::function<int()>就是一个可调用对象模板类,代表一个可调用对象,接受 0 个参数,返回值是int。所以,当我们需要一个接受一个double作为参数,返回int的对象时,就可以写作:std::function<int(double)>
引入 lambda 表达式的前导符是一对方括号,称为 lambda 引入符(lambda-introducer)。lambda 引入符是有其自己的作用的,不仅仅是表明一个 lambda 表达式的开始那么简单。lambda 表达式可以使用与其相同范围 scope 内的变量。这个引入符的作用就是表明,其后的 lambda 表达式以何种方式使用(正式的术语是“捕获”)这些变量(这些变量能够在 lambda 表达式中被捕获,其实就是构成了一个闭包)。目前为止,我们看到的仅仅是一个空的方括号,其实,这个引入符是相当灵活的。例如:
其输出值是 4.5。[=] 意味着,lambda 表达式以传值的形式捕获同范围内的变量。另外一个例子:
输出值是 4.5 和 4.5。[&] 表明,lambda 表达式以传引用的方式捕获外部变量。那么,下一个例子:
这个例子很有趣。首先,[=]意味着,lambda 表达式以传值的形式捕获外部变量。C++ 11 标准说,如果以传值的形式捕获外部变量,那么,lambda 体不允许修改外部变量,对 f0 的任何修改都会引发编译错误。但是,注意,我们在 lambda 表达式前声明了mutable关键字,这就允许了 lambda 表达式体修改 f0 的值。因此,我们的例子本应报错,但是由于有 mutable 关键字,则不会报错。那么,你会觉得输出值是什么呢?答案是,4.5 和 1.0。为什么 f0 还是 1.0?因为我们是传值的,虽然在 lambda 表达式中对 f0 有了修改,但由于是传值的,外部的 f0 依然不会被修改。
上面的例子是,所有的变量要么传值,要么传引用。那么,是不是有混合机制呢?当然也有!比如下面的例子:
这个例子的输出是 14.5 和 14.5。在这个例子中,f0 通过引用被捕获,而其它变量,比如 f1 则是通过值被捕获。
下面我们来总结下所有出现的 lambda 引入符:
  • []        // 不捕获任何外部变量
  • [=]      // 以值的形式捕获所有外部变量
  • [&]      // 以引用形式捕获所有外部变量
  • [x, &y] // x 以传值形式捕获,y 以引用形式捕获
  • [=, &z]// z 以引用形式捕获,其余变量以传值形式捕获
  • [&, x]  // x 以值的形式捕获,其余变量以引用形式捕获
另外有一点需要注意。对于[=][&]的形式,lambda 表达式可以直接使用 this 指针。但是,对于[]的形式,如果要使用 this 指针,必须显式传入:
至此,我们已经大致了解了 C++ 11 提供的 lambda 表达式的概念。建议通过结合 lambda 表达式与std::sort()std::for_each()这样的标准函数来尝试使用一下吧!