当前位置: 首页 > 编程日记 > 正文

C++/C++11中左值、左值引用、右值、右值引用的使用

C++的表达式要不然是右值(rvalue),要不然就是左值(lvalue)。这两个名词是从C语言继承过来的,原本是为了帮助记忆:左值可以位于赋值语句的左侧,右值则不能。

在C++语言中,二者的区别就没那么简单了。一个左值表达式的求值结果是一个对象或者一个函数,然而以常量对象为代表的某些左值实际上不能作为赋值语句的左侧运算对象。此外,虽然某些表达式的求值结果是对象,但它们是右值而非左值。可以做一个简单的归纳:当一个对象被用作右值的时候,用的是对象的值(内容);当对象被用作左值的时候,用的是对象的身份(在内存中的位置)左值与右值的根本区别在于是否允许取地址&运算符获得对应的内存地址

不同的运算符对运算对象的要求各不相同,有的需要左值运算对象,有的需要右值运算对象;返回值也有差异,有的得到左值结果,有的得到右值结果。一个重要的原则(有一种例外的情况),是在需要右值的地方可以用左值来代替,但是不能把右值当成左值(也就是位置)使用。当一个左值被当成右值使用时,实际使用的是它的内容(值)。

运算符用到左值的包括:(1).赋值运算符需要一个(非常量)左值作为其左侧运算对象,得到的结果也仍然是一个左值。(2).取地址符作用于一个左值运算对象,返回一个指向该运算对象的指针,这个指针是一个右值。(3). 内置解引用运算符、下标运算符、迭代器解引用运算符、string和vector的下标运算符的求值结果都是左值。(4). 内置类型和迭代器的递增递减运算符作用于左值运算对象,其前置版本所得的结果也是左值。

使用关键字decltype的时候,左值和右值也有所不同。如果表达式的求值结果是左值,decltype作用于该表达式(不是变量)得到一个引用类型。举个例子,假定p的类型是int*,因为解引用运算符生成左值,所以decltype(*p)的结果是int&。另一方面,因为取地址运算符生成右值,所以decltype(&p)的结果是int**,也就是说,结果是一个指向整型指针的指针。

赋值运算符的左侧运算对象必须是一个可修改的左值。赋值运算符的结果是它的左侧运算对象,并且是一个左值。相应的,结果的类型就是左侧运算对象的类型。如果赋值运算符的左右两个运算对象类型不同,则右侧运算对象将转换成左侧运算对象的类型。

递增和递减运算符有两种形式:前置版本和后置版本。这两种运算符必须作用于左值运算对象。前置版本将对象本身作为左值返回,后置版本则将对象原始值的副本作为右值返回。

箭头运算符作用于一个指针类型的运算对象,结果是一个左值。点运算符分成两种情况:如果成员所属的对象是左值,那么结果是左值;反之,如果成员所属的对象是右值,那么结果是右值。

当条件运算符的两个表达式都是左值或者能转换成同一种左值类型时,运算的结果是左值;否则运算的结果是右值。

对于逗号运算符来说,首先对左侧的表达式求值,然后将求值结果丢弃掉。逗号运算符真正的结果是右侧表达式的值。如果右侧运算对象是左值,那么最终的求值结果也是左值。

左值(lvalue):是指那些求值结果为对象或函数的表达式。一个表示对象的非常量左值可以作为赋值运算符的左侧运算对象。

右值(rvalue):是指一种表达式,其结果是值而非值所在的位置。

函数返回类型:函数的返回类型决定函数调用是否是左值。调用一个返回引用的函数得到左值,其它返回类型得到右值。可以像使用其它左值那样来使用返回引用的函数的调用,特别是,我们能为返回类型是非常量引用的函数的结果赋值。把函数调用放在赋值语句的左侧可能看起来有点奇怪,但其实这没什么特别的。返回值是引用,因此调用是个左值,和其它左值一样它也能出现在赋值运算符的左侧。如果返回类型是常量引用,我们不能给调用的结果赋值,这一点和我们熟悉的情况是一样的。

严格来说,当我们使用术语”引用(reference)”时,指的其实是”左值引用(lvalue reference)”。C++11中新增了一种引用,右值引用(rvalue reference),这种引用主要用于内置类。

为了支持移动操作,C++11引入了一种新的引用类型----右值引用(rvalue reference)。所谓右值引用就是必须绑定到右值的引用通过&&而不是&来获得右值引用右值引用有一个重要的性质----只能绑定到一个将要销毁的对象。因此,可以自由地将一个右值引用的资源”移动”到另一个对象中。

左值和右值是表达式的属性。一些表达式生成或要求左值,而另外一些则生成或要求右值。一般而言,一个左值表达式表示的是一个对象的身份,而一个右值表达式表示的是对象的值。

类似任何引用,一个右值引用也不过是某个对象的另一个名字而已。对于常规引用(为了与右值引用区分开来,可以称之为左值引用(lvalue reference)),不能将其绑定到要求转换的表达式、字面常量或是返回右值的表达式。右值引用有着完全相反的绑定特性:可以将一个右值引用绑定到这类表达式上,但不能将一个右值引用直接绑定到一个左值上

返回左值引用的函数,连同赋值、下标、解引用和前置递增/递减运算符,都是返回左值的表达式的例子。可以将一个左值引用绑定到这类表达式的结果上。

返回非引用类型的函数,连同算术、关系、位以及后置递增/递减运算符,都生成右值。不能将一个左值引用绑定到这类表达式上,但可以将一个const的左值引用或者一个右值引用绑定到这类表达式上

左值持久,右值短暂:左值有持久的状态,而右值要么是字面常量,要么是在表达式求值过程中创建的临时对象。

由于右值引用只能绑定到临时对象,可知:所引用的对象将要被销毁;该对象没有其它用户。这两个特性意味着,使用右值引用的代码可以自由地接管所引用的对象的资源。右值引用指向将要销毁的对象。因此,我们可以从绑定到右值引用的对象”窃取”状态。

变量是左值:变量可以看作只有一个运算对象而没有运算符的表达式,虽然我们很少这样看待变量。类似其它任何表达式,变量表达式也有左值/右值属性。变量表达式都是左值。带来的结果就是,我们不能将一个右值引用绑定到一个右值引用类型的变量上。其实有了右值表示临时对象这一观察结果,变量是左值这一特性并不令人惊讶。毕竟,变量是持久的,直至离开作用域时才被销毁。变量是左值,因此我们不能将一个右值引用直接绑定到一个变量上,即使这个变量是右值引用类型也不行。

标准库std::move函数:虽然不能将一个右值引用直接绑定到一个左值上,但可以显示地将一个左值转换为对应的右值引用类型。我们还可以通过调用一个名为move的新标准库函数来获得绑定到左值上的右值引用,此函数定义在头文件utility中。move调用告诉编译器:有一个左值,但希望像一个右值一样处理它。我们必须认识到,在调用move之后,我们不能对移后源对象的值做任何假设。我们可以销毁一个移后源对象,也可以赋予它新值,但不能使用一个移后源对象的值

移动构造函数和移动赋值运算符接受一个(通常是非const的)右值引用;而拷贝版本则接受一个(通常是const的)普通左值引用。

左值引用(lvalue reference):可以绑定到左值的引用。右值引用(rvalue reference):指向一个将要销毁的对象的引用。

引用限定符(referencequalifier):用来指出一个非static成员函数可以用于左值或右值的符号。限定符&和&&应该放在参数列表之后或const限定符之后(如果有的话)。被&限定的函数只能用于左值;被&&限定的函数只能用于右值。

如果一个函数参数是指向模板参数类型的右值引用(如,T&&),则可以传递给它任意类型的实参。如果将一个左值传递给这样的参数,则函数参数被实例化为一个普通的左值引用(T&)。

右值引用是C++11中最重要的新特性之一,它解决了C++中大量的历史遗留问题,使C++标准库的实现在多种场景下消除了不必要的额外开销(如std::vector, std::string),也使得另外一些标准库(如std::unique_ptr,std::function)成为可能。即使你并不直接使用右值引用,也可以通过标准库,间接从这一新特性中受益。

右值引用的意义通常解释为两大作用:移动语义(Move Sementics)和完美转发(Perfect Forwarding)。它的主要目的有两个方面:(1)、消除两个对象交互时不必要的对象拷贝,节省运算存储资源,提高效率;(2)、能够更简洁明确地定义泛型函数。

右值引用可以使我们区分表达式的左值和右值。

右值引用主要就是解决一个拷贝效率低下的问题,因为针对于右值,或者打算更改的左值,我们可以采用类似与unique_ptr的move(移动)操作,大大的提高性能(move semantics)。另外,C++的模板推断机制为参数T&&做了一个例外规则,让左值和右值的识别和转向(forward)非常简单,帮助我们写出高效并且简捷的泛型代码(perfect forwarding)。

下面是从其他文章中copy的测试代码,详细内容介绍可以参考对应的reference:

#include "lvalue_rvalue.hpp"
#include <iostream>
#include <string>
#include <utility>namespace lvalue_rvalue_ {namespace {
char& get_val(std::string& str, std::string::size_type ix)
{return str[ix];
}
}int test_lvalue_rvalue_1()
{
{// 赋值运算符的左侧运算对象必须是一个可修改的左值:int i = 0, j = 0, k = 0; // 初始化而非赋值const int ci = i; // 初始化而非赋值// 下面的赋值语句都是非法的//1024 = k; // 错误:字面值是右值//i + j = k; // 错误:算术表达式是右值//ci = k; // 错误:ci是常量(不可修改的)左值
}{int i = 0;int& r = i; // 正确:r引用i//int&& rr = i; // 错误:不能将一个右值引用绑定到一个左值上//int& r2 = i * 42; // 错误:i*42是一个右值const int& r3 = i * 42; // 正确:我们可以将一个const的引用绑定到一个右值上int&& rr2 = i * 42; // 正确:将rr2绑定到乘法结果上
}{// 不能将一个右值引用绑定到一个右值引用类型的变量上int&& rr1 = 42; // 正确:字面常量是右值//int&& rr2 = rr1; // 错误:表达式rr1是左值//int rr = &&rr1; // 不能将一个右值引用直接绑定到一个左值上int i = 5;int&& rr3 = std::move(i); // ok}// 调用一个返回引用的函数得到左值,其它返回类型得到右值std::string s{ "a value" };std::cout << s << std::endl; // a valueget_val(s, 0) = 'A';std::cout << s << std::endl; // A valuereturn 0;
}/
// reference: https://msdn.microsoft.com/en-us/library/f90831hc.aspx
int test_lvalue_rvalue_2()
{int i, j;int *p = new int;// Correct usage: the variable i is an lvalue.i = 7;// Incorrect usage: The left operand must be an lvalue (C2106).//7 = i; // C2106//j * 4 = 7; // C2106// Correct usage: the dereferenced pointer is an lvalue.*p = i;delete p;const int ci = 7;// Incorrect usage: the variable is a non-modifiable lvalue (C3892).//ci = 9; // C3892// Correct usage: the conditional operator returns an lvalue.((i < 3) ? i : j) = 7;return 0;
}//
// reference: http://www.bogotobogo.com/cplusplus/C11/4_C11_Rvalue_Lvalue.php
namespace {class cat {};int square(int x) { return x*x; }int square2(int& x) { return x*x; }
}int test_lvalue_rvalue_3()
{
{ // lvalue examplesint i = 7;  // i: lvalueint *pi = &i;  // i is addressablei = 10;  // we can modify itclass cat {};cat c;   // c is an lvalue for a user defined type
}{ // rvalue examplesint i = 7;  // i: lvalue but 7 is rvalueint k = i + 3;  // (i+3) is an rvalue//int *pi = &(i + 3); // error, it's not addressable//i + 3 = 10;   // error - cannot assign a value to it//3 = i;        // error - not assignablecat c;c = cat();   // cat() is an rvalue}{int sq = square(10);  // square(10) is an rvalue
}{int i = 7;square(i);  // OKsquare(7);//square2(7);  // error, 7 is an rvalue and cannot be assigned to a reference
}{int a = 7; // a is lvalue & 7 is rvalueint b = (a + 2); // b is lvalue & (a+2) is rvalueint c = (a + b); // c is lvalue & (a+b) is rvalueint * ptr = &a; // Possible to take address of lvalue//int * ptr3 = &(a + 1);  // Compile Error. Can not take address of rvalue
}return 0;
}//
// reference: http://en.cppreference.com/w/cpp/language/reference
namespace {
void double_string(std::string& s)
{s += s; // 's' is the same object as main()'s 'str'
}char& char_number(std::string& s, std::size_t n)
{return s.at(n); // string::at() returns a reference to char
}
}int test_lvalue_rvalue_4()
{// 1. Lvalue references can be used to alias an existing object (optionally with different cv-qualification):std::string s = "Ex";std::string& r1 = s;const std::string& r2 = s;r1 += "ample";           // modifies s//  r2 += "!";               // error: cannot modify through reference to conststd::cout << r2 << '\n'; // prints s, which now holds "Example"// 2. They can also be used to implement pass-by-reference semantics in function calls:std::string str = "Test";double_string(str);std::cout << str << '\n';// 3. When a function's return type is lvalue reference, the function call expression becomes an lvalue expressionstd::string str_ = "Test";char_number(str_, 1) = 'a'; // the function call is lvalue, can be assigned tostd::cout << str_ << '\n';return 0;
}/
// reference: http://en.cppreference.com/w/cpp/language/reference
namespace {
void f(int& x)
{std::cout << "lvalue reference overload f(" << x << ")\n";
}void f(const int& x)
{std::cout << "lvalue reference to const overload f(" << x << ")\n";
}void f(int&& x)
{std::cout << "rvalue reference overload f(" << x << ")\n";
}
}int test_lvalue_rvalue_5()
{// 1. Rvalue references can be used to extend the lifetimes of temporary objects// (note, lvalue references to const can extend the lifetimes of temporary objects too, but they are not modifiable through them):std::string s1 = "Test";//  std::string&& r1 = s1;           // error: can't bind to lvalueconst std::string& r2 = s1 + s1; // okay: lvalue reference to const extends lifetime//  r2 += "Test";                    // error: can't modify through reference to conststd::string&& r3 = s1 + s1;      // okay: rvalue reference extends lifetimer3 += "Test";                    // okay: can modify through reference to non-conststd::cout << r3 << '\n';// 2. More importantly, when a function has both rvalue reference and lvalue reference overloads,// the rvalue reference overload binds to rvalues (including both prvalues and xvalues),// while the lvalue reference overload binds to lvalues:int i = 1;const int ci = 2;f(i);  // calls f(int&)f(ci); // calls f(const int&)f(3);  // calls f(int&&)// would call f(const int&) if f(int&&) overload wasn't providedf(std::move(i)); // calls f(int&&)// This allows move constructors, move assignment operators, and other move-aware functions// (e.g. vector::push_back() to be automatically selected when suitable.return 0;
}/
// reference: http://www.bogotobogo.com/cplusplus/C11/5_C11_Move_Semantics_Rvalue_Reference.php
namespace {
void printReference(int& value)
{std::cout << "lvalue: value = " << value << std::endl;
}void printReference(int&& value)
{std::cout << "rvalue: value = " << value << std::endl;
}int getValue()
{int temp_ii = 99;return temp_ii;
}
}int test_lvalue_rvalue_6()
{int ii = 11;printReference(ii);printReference(getValue());  //  printReference(99);return 0;
}// reference: https://msdn.microsoft.com/en-us/library/dd293668.aspx
namespace {
template<typename T> struct S;// The following structures specialize S by 
// lvalue reference (T&), const lvalue reference (const T&), 
// rvalue reference (T&&), and const rvalue reference (const T&&).
// Each structure provides a print method that prints the type of 
// the structure and its parameter.
template<typename T> struct S<T&> {static void print(T& t){std::cout << "print<T&>: " << t << std::endl;}
};template<typename T> struct S<const T&> {static void print(const T& t){std::cout << "print<const T&>: " << t << std::endl;}
};template<typename T> struct S<T&&> {static void print(T&& t){std::cout << "print<T&&>: " << t << std::endl;}
};template<typename T> struct S<const T&&> {static void print(const T&& t){std::cout << "print<const T&&>: " << t << std::endl;}
};// This function forwards its parameter to a specialized
// version of the S type.
template <typename T> void print_type_and_value(T&& t)
{S<T&&>::print(std::forward<T>(t));
}// This function returns the constant string "fourth".
const std::string fourth() { return std::string("fourth"); }
}int test_lvalue_rvalue_7()
{// The following call resolves to:// print_type_and_value<string&>(string& && t)// Which collapses to:// print_type_and_value<string&>(string& t)std::string s1("first");print_type_and_value(s1);// The following call resolves to:// print_type_and_value<const string&>(const string& && t)// Which collapses to:// print_type_and_value<const string&>(const string& t)const std::string s2("second");print_type_and_value(s2);// The following call resolves to:// print_type_and_value<string&&>(string&& t)print_type_and_value(std::string("third"));// The following call resolves to:// print_type_and_value<const string&&>(const string&& t)print_type_and_value(fourth());return 0;
}} // namespace lvalue_rvalue_

GitHub:https://github.com/fengbingchun/Messy_Test

相关文章:

Could not create the view: An unexpected exception was thrown. Myeclipse空间报错

转载于:https://blog.51cto.com/82654993/1424339

Banknote Dataset(钞票数据集)介绍

Banknote Dataset(钞票数据集)&#xff1a;这是从纸币鉴别过程中的图像里提取的数据&#xff0c;用来预测钞票的真伪的数据集。该数据集中含有1372个样本&#xff0c;每个样本由5个数值型变量构成&#xff0c;4个输入变量和1个输出变量。小波变换工具用于从图像中提取特征。这是…

快速适应性很重要,但不是元学习的全部目标

作者 | Khurram Javed, Hengshuai Yao, Martha White译者 | Monanfei出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;实践证明&#xff0c;基于梯度的元学习在学习模型初始化、表示形式和更新规则方面非常有效&#xff0c;该模型允许从少量样本中进行快速适应。这些方…

面试题-自旋锁,以及jvm对synchronized的优化

背景 想要弄清楚这些问题&#xff0c;需要弄清楚其他的很多问题。 比如&#xff0c;对象&#xff0c;而对象本身又可以延伸出很多其他的问题。 我们平时不过只是在使用对象而已&#xff0c;怎么使用&#xff1f;就是new 对象。这只是语法层面的使用&#xff0c;相当于会了一门编…

DNS解析故障

在实际应用过程中可能会遇到DNS解析错误的问题&#xff0c;就是说当我们访问一个域名时无法完成将其解析到IP地址的工作&#xff0c;而直接输入网站IP却可以正常访问&#xff0c;这就是因为DNS解析出现故障造成的。这个现象发生的机率比较大&#xff0c;所以本文将从零起步教给…

cinder存储服务

一、cinder 介绍&#xff1a; 理解 Block Storage 操作系统获得存储空间的方式一般有两种&#xff1a; 1、通过某种协议&#xff08;SAS,SCSI,SAN,iSCSI 等&#xff09;挂接裸硬盘&#xff0c;然后分区、格式化、创建文件系统&#xff1b;或者直接使用裸硬盘存储数据&#xff0…

Ubuntu 14.04 64位机上配置Android Studio操作步骤

Android Studio是一个为Android平台开发程序的集成开发环境。2013年5月16日在Google I/O上发布&#xff0c;可供开发者免费使用。Android Studio基于JetBrains IntelliJ IDEA&#xff0c;为Android开发特殊定制&#xff0c;并在Windows、OS X和Linux平台上均可运行。1. 从 htt…

大规模1.4亿中文知识图谱数据,我把它开源了

作者 | Just出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;人工智能从感知阶段逐步进入认知智能的过程中&#xff0c;知识图谱技术将为机器提供认知思维能力和关联分析能力&#xff0c;可以应用于机器人问答系统、内容推荐等系统中。不过要降低知识图谱技术应用的门…

使用CSS 3创建不规则图形

2019独角兽企业重金招聘Python工程师标准>>> 前言 CSS 创建复杂图形的技术即将会被广泛支持&#xff0c;并且应用到实际项目中。本篇文章的目的是为大家开启它的冰山一角。我希望这篇文章能让你对不规则图形有一个初步的了解。 现在&#xff0c;我们已经可以使用CSS…

谷歌丰田联合成果ALBERT了解一下:新轻量版BERT,参数小18倍,性能依旧SOTA

作者 | Less Wright编译 | ronghuaiyang来源 | AI公园&#xff08;ID:AI_Paradise&#xff09;【导读】这是来自Google和Toyota的新NLP模型&#xff0c;超越Bert&#xff0c;参数小了18倍。你以前的NLP模型参数效率低下&#xff0c;而且有些过时。祝你有美好的一天。谷歌Resear…

C++中extern C的使用

C程序有时需要调用其它语言编写的函数&#xff0c;最常见的是调用&#xff23;语言编写的函数。像所有其它名字一样&#xff0c;其它语言中的函数名字也必须在C中进行声明&#xff0c;并且该声明必须指定返回类型和形参列表。对于其它语言编写的函数来说&#xff0c;编译器检查…

Linux之tmpwatch命令

1、tmpwatch命令功能简介[rootvms002 /]# whatis tmpwatch tmpwatch (8) - removes files which havent been accessed for a period of... #删除一段时间内未被访问的文件tmpwatch删除最近一段时间内没有被访问的文件&#xff0c;时间以小时为单位&#xff0c;节省磁盘空间。…

你不得不知道的Visual Studio 2012(1)- 每日必用功能

2019独角兽企业重金招聘Python工程师标准>>> Visual Studio 2012已经正式发布&#xff0c;有很多花哨的新特性&#xff0c;也有很多方便使用者的新功能&#xff0c;当然也有负面声音。对于我们程序员&#xff0c;最关心的还是如何快速掌握VS2012&#xff0c;用于平时…

C++11中std::unique_lock的使用

std::unique_lock为锁管理模板类&#xff0c;是对通用mutex的封装。std::unique_lock对象以独占所有权的方式(unique owership)管理mutex对象的上锁和解锁操作&#xff0c;即在unique_lock对象的声明周期内&#xff0c;它所管理的锁对象会一直保持上锁状态&#xff1b;而unique…

为何Google将几十亿行源代码放在一个仓库?| CSDN博文精选

作者 | Rachel Potvin&#xff0c;Josh Levenberg译者 | 张建军编辑 | apddd【AI科技大本营导读】与大多数开发者的想象不同&#xff0c;Google只有一个代码仓库——全公司使用不同语言编写的超过10亿文件&#xff0c;近百TB源代码都存放在自行开发的版本管理系统Piper中&#…

小小hanoi

为什么80%的码农都做不了架构师&#xff1f;>>> View Code #include " iostream " using namespace std; int k 0 ; void hanoi( int m , char a , char b, char c){ if (m 1 ) { k ; printf( " %c->%c " ,a , c); return…

Unity3D心得分享

本篇文章的内容以各种tips为主&#xff0c;不间断更新 2019/05/10 最近更新&#xff1a; 使用Instantiate初始化参数去实例对象 Unity DEMO学习 Unity3D Adam Demo的学习与研究 Unity3D The Blacksmith Demo部分内容学习 Viking Village维京村落demo中的地面积水效果 Viking V…

django搭建示例-ubantu环境

python3安装--------------------------------------------------------------------------- 最新的django依赖python3,同时ubantu系统默认自带python2与python3&#xff0c;这里单独安装一套python3&#xff0c;并且不影响原来的python环境 django demo使用sqlite3&#xff0c…

C++11中std::lock_guard的使用

互斥类的最重要成员函数是lock()和unlock()。在进入临界区时&#xff0c;执行lock()加锁操作&#xff0c;如果这时已经被其它线程锁住&#xff0c;则当前线程在此排队等待。退出临界区时&#xff0c;执行unlock()解锁操作。更好的办法是采用”资源分配时初始化”(RAII)方法来加…

OpenAI机械手单手轻松解魔方,背靠强化学习+新技术ADR

编译 | 夕颜出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;【导读】10月15日&#xff0c;人工智能研究机构OpenAI发布了一条机械手单手解魔方的视频。这个自学式的类人机器人手臂名为 Dactyl&#xff0c;不仅可以单手解魔方&#xff0c;甚至能在外加各种干扰&#x…

AMD and CMD are dead之js模块化黑魔法

缘由 在2013-03-06 13:58的时候&#xff0c;曾甩下一片文章叫&#xff1a;《为什么不使用requirejs和seajs》&#xff0c;并放下豪言说发布一款完美的模块化库&#xff0c;再后来就把那篇文章删了&#xff0c;再然后就没有然后。该用seajs还用seajs&#xff0c;甚至我码的SCJ都…

一文了解Python常见的序列化操作

关于我 编程界的一名小小程序猿&#xff0c;目前在一个创业团队任team lead&#xff0c;技术栈涉及Android、Python、Java和Go&#xff0c;这个也是我们团队的主要技术栈。 联系&#xff1a;hylinux1024gmail.com 0x00 marshal marshal使用的是与Python语言相关但与机器无关的二…

TEE(Trusted Execution Environment)简介

TEE(Trusted Execution Environment)&#xff0c;可信执行环境&#xff0c;该环境可以保证不被常规操作系统干扰的计算&#xff0c;因此称为”可信”。这是通过创建一个可以在TrustZone的”安全世界”中独立运行的小型操作系统实现的&#xff0c;该操作系统以系统调用(由TrustZ…

自动驾驶关键环节:行人的行为意图建模和预测(上)

作者 | 黄浴出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;【导读】介绍一下最近行人行为意图建模和预测的研究工作&#xff0c;还是分上下两部分&#xff0c;本文为上半部分。Social LSTM: Human Trajectory Prediction in Crowded Spaces比较早的是斯坦福大学 201…

自定义windows下自动清除文件夹或者文件的只读属性的脚本

脚本内容入下&#xff1a;其中脚本中 ”/d"作用 &#xff08;可以用来改变当前驱动器目录&#xff09;例如&#xff1a; 我现在是在D盘&#xff0c;现在我要切换到C:\windows目录 脚本参数中 ATTRIB -R /S /D 解释内容如下&#xff1a;&#xff08;上述脚本参数中的 cd …

C++11容器中新增加的emplace相关函数的使用

C11中&#xff0c;针对顺序容器(如vector、deque、list)&#xff0c;新标准引入了三个新成员&#xff1a;emplace_front、emplace和emplace_back&#xff0c;这些操作构造而不是拷贝元素。这些操作分别对应push_front、insert和push_back&#xff0c;允许我们将元素放置在容器头…

Silverlight+WCF 新手实例 象棋 主界面-棋谱-获取列表(三十八)

2019独角兽企业重金招聘Python工程师标准>>> 在线演示地址&#xff1a;SilverlightWCF 新手实例 象棋 在线演示 在SilverlightWCF 新手实例 象棋 主界面-棋谱-布局写谱(三十六)中&#xff0c;我们完成下棋双方的棋谱显示&#xff0c;这节&#xff0c;我们为观众增加…

确认!语音识别大牛Daniel Povey将入职小米,曾遭霍普金斯大学解雇,怒拒Facebook

整理 | 夕颜 出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09; 【导读】10 月 17 日&#xff0c;语音界传奇 Daniel Povey 发布推特&#xff0c;宣布自己 2019 年末将要入职小米&#xff0c;目前正在签订合同阶段&#xff0c;入职后&#xff0c;他将带领一支团队研发…

软链接与硬链接

$ ln f1 f2 #创建f1的一个硬连接文件f2$ ln -s f1 f3 #创建f1的一个符号连接文件f3$ ls -li # -i参数显示文件的inode节点信息转载于:https://www.cnblogs.com/zhizouxiao/p/3794668.html

一文读懂Python复杂网络分析库networkx | CSDN博文精选

作者 | yyl424525来源 | CSDN博客文章目录1. 简介安装支持四种图绘制网络图基本流程2. Graph-无向图节点边属性有向图和无向图互转3. DiGraph-有向图一些精美的图例子环形树状图权重图Giant ComponentRandom Geometric Graph 随机几何图节点颜色渐变边的颜色渐变Atlas画个五角星…