C++11:&&右值引用、std::ref与std::unique_ptr

非常容易混淆的三种语法,在新手看来含义似乎相同,都是在函数调用上参数的传递,但实际上有非常大的区别。下面我们来具体分析分析。
首先是&&右值引用,在说这个之前先得弄清什么是右值。右值也叫将亡值(这翻译简直(¬_¬)),顾名思义也就是说将会死亡的值。比如类似这样的代码:

1
std::string s = std::string("abc");

从原理上来说,这句代码的含义是,首先在等号右侧构建一个临时字符串对象,然后将右侧对象执行拷贝构造,拷贝至变量s中,然后释放等号右侧对象(实际的实现中,编译器通常会对这样的代码进行优化,直接在变量s中构建字符串对象)。
如果上面的例子不太明显那么再来一个例子,Gdi+中经常会出现这样的代码:

1
2
Gdiplus::Graphics g(&img);
g.DrawImage(&img2, &Gdiplus::Rect(0, 0, 10, 10), ...);

似曾相识的代码对吧?这儿的DrawImage函数在执行前首先构造匿名Gdiplus::Rect对象,然后作为参数传递,函数调用返回时,也就是这行代码执行完时,匿名对象将被释放。这也是它被叫做将亡值的原因。
既然这种对象在使用时生命周期短,拷贝至左值又可能会影响效率,那有没更好的引用方式呢?当然有,这叫右值引用。
继续阅读C++11:&&右值引用、std::ref与std::unique_ptr

C++11:std::bind实现参数动态绑定

参数动态绑定在实际编程中用的不多,但在特定情况下非常有用。这个功能的意思是,将函数与参数绑定,下次调用时可以不用再次麻烦的传递参数。首先给出一个示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <string>
#include <functional>
using namespace std;
 
void func (int i, int j) {
    cout < < "i = " << i << ", j = " << j << endl;
}
 
int main(int argc, char* argv[]) {
    function<void (int, int)> f = func;
    f (1, 2);
    return 0;
}</functional></string></iostream>

结果为i = 1, j = 2
以上例子是使用函数对象保存函数地址,然后调用函数对象的示例代码,下面我让函数对象f与参数进行绑定:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <string>
#include <functional>
using namespace std;
 
void func (int i, int j) {
    cout < < "i = " << i << ", j = " << j << endl;
}
 
int main(int argc, char* argv[]) {
    function<void ()> f = bind(func, 1, 2);
    f ();
    return 0;
}</functional></string></iostream>

结果为i = 1, j = 2
由于已经绑定了参数1和2,所以在实际调用时不用再次赋值。注意函数对象的声明。
继续阅读C++11:std::bind实现参数动态绑定