在2017-7-02的日志中存疑的地方在于,貌似folly库用了一种方法把所有的值都变成了左值引用。

当时用了一个小程序来推测这个问题:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
auto transform(std::string && a)
{
  		std::cout << &a << std::endl;
  	 	return std::ref(a);
}
int main() 
{

 	auto a = transform("hahaha");
   	std::string &r = a.get();
   	std::cout << &r << std::endl;
  	r[0] = 'b';
    std::cout << r << std::endl;
}

实际上,这里"hahaha"是一个右值,而且会生成一个临时对象std::string,并用这个临时对象来初始化a,但是是否这个临时对象的生存期就在transform这个函数中呢?如果如此,那么该程序会core掉。

实际上改成如下程序之后,程序确实core掉了:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
std::string && make_string()
{
     return "hahaha";
}

auto transform(std::string && a)
{
  		std::cout << &a << std::endl;
  	 	return std::ref(a);
}
int main() 
{

 	auto a = transform(make_string());
   	std::string &r = a.get();
   	std::cout << &r << std::endl;
}


因此事情的本质在于,对象的生存期是否被延长了?而不是左值右值的变化,实际上变来变去都无所谓,只要所指向的对象还活着,都没有问题。C++只是禁止用一个临时对象初始化给一个非const引用,但是实际上有很多种方法可以绕开这种语法检查,而做到操作临时变量的内存,在stackoverflow上有很多人提出了更简单的方法避开这种语法检查,所以没有必要纠结于细节。

我因此怀疑,实际上"hahaha"这个临时对象的生存期是在main函数中,而非transform函数中的。