【C++】C++11语法之右值引用

2023-11-20


一、{}的扩展

在原先c++的基础上,C++11扩展了很多初始化的方法。

#include<iostream>
using namespace std;

struct A
{
	int _x;
	int _y;
};
int main()
{
	int a[] = { 1,2,3,4,5 };
	
	int a1[] { 1,2,3,4,5 };
	int* p = new int[5]{ 1,2,3,4,5 };
	A b = { 1,2 };//初始化
	A b2[5]{ {1,1},{2,2},{3,3},{4,4},{5,5} };
	A* pb = new A{ 1,2 };
	A* pb2 = new A[5]{ {1,1},{2,2},{3,3},{4,4},{5,5} };

	return 0;
}

结果:

全部初始化正常,vs下指针后面跟数字可以表示显示多少个。
在这里插入图片描述

除了上面的 new[]{}我认为是比较有意义的,很好的解决了new的对象没有构造函数又需要同时创建多个对象的场景。

除了上面的,下面的这种方式底层实现不相同。

initializer_list的讲解:

vector<int> v{1,2,3,4};

在这里插入图片描述
跳转initializer_list实现
实际上上面就是通过传参给initializer_list对象,这个对象相当于浅拷贝了外部的{1,2,3,4}的头指针和尾指针,这样vector的构造函数就可以通过迭代器遍历的方式一个个的push_back到自己的容器当中。上述过程initializer_list是很高效的,因为他只涉及浅拷贝指针和一个整形。

#include <iostream>

template <class T>
class initializer_list
{
public:
    typedef T         value_type;
    typedef const T&  reference; //注意说明该对象永远为const,不能被外部修改!
    typedef const T&  const_reference;
    typedef size_t    size_type;
    typedef const T*  iterator;  //永远为const类型
    typedef const T*  const_iterator;
private:
    iterator    _M_array; //用于存放用{}初始化列表中的元素
    size_type   _M_len;   //元素的个数
    
    //编译器可以调用private的构造函数!!!
    //构造函数,在调用之前,编译会先在外部准备好一个array,同时把array的地址传入模板
    //并保存在_M_array中
    constexpr initializer_list(const_iterator __a, size_type __l)
    :_M_array(__a),_M_len(__l){};  //注意构造函数被放到private中!

    constexpr initializer_list() : _M_array(0), _M_len(0){} // empty list,无参构造函数
    
    //size()函数,用于获取元素的个数
    constexpr size_type size() const noexcept {return _M_len;}
    
    //获取第一个元素
    constexpr const_iterator begin() const noexcept {return _M_array;}
    
    //最后一个元素的下一个位置
    constexpr const_iterator end() const noexcept
    {
        return begin() + _M_len;
    }  
};

在这里插入图片描述

而{}初始化,和{}调用initializer_list组合起来是可以让初始化变得方便起来的,下面的m0用了initializer_list进行初始化,但还是比较麻烦。但m1用了{}进行单个对象初始化加initializer_list的组合之后变得方便快捷起来。

#include<map>
int main()
{
	map<int, int> m0 = { pair<int,int>(1,1), pair<int,int>(2,2), pair<int,int>(3,3) };
	
	map<int, int> m1= { {1,1},{2,2},{3,3} };

	return 0;
}

小总结:

一个自定义类型调用{}初始化,本质是调用对应的构造函数;自定义类型对象可以使用{}初始化,必须要有对应的参数类型和个数;STL容器支持{}初始化,则容器必须有一个initializer_list作为参数的构造函数。

二、C++11一些小的更新

auto:
定义变量前加auto表示自动存储,表示不用管对象的销毁,但是默认定义的就是自动类型,所以这个关键字后面就不这样用了,C++11中改成了自动推导类型。

#include<cstring>
int main()
{
	int i = 10;
	auto p = &i;
	auto pf = strcmp;

	cout << typeid(p).name() << endl;
	cout << typeid(pf).name() << endl;
	return 0;
}

结果:

int *
int (__cdecl*)(char const *,char const *)

decltype

auto只能推导类型,但推导出来的类型不能用来定义对象,decltype解决了这点,推导类型后可以用来定义对象。
decltype(表达式,变量),不能放类型!

#include<cstring>
int main()
{
	int i = 10;
	auto p = &i;
	auto pf = strcmp;

	decltype(p) pi;//int*
	pi = &i;
	cout << *pi << endl;//10
	return 0;
}

nullptr

NULL在C中是0,是int类型。C++11添加nullptr表示((void*)0),避免匹配错参数。

范围for

支持迭代器就支持范围for

新容器

array,没啥用,静态的数组,不支持push_back,支持方括号,里面有assert断言防止越界,保证了安全。

foward_list,没啥用,单链表,只能在节点的后面插入。

unordered_map,很有用,后面讲

unordered_set,很有用,后面讲

三、右值引用

左值
作指示一个数据表达式(变量名或解引用的指针)。
左值可以在赋值符号左右边,右值不能出现在赋值符号的左边。

const修饰符后的左值,不能给他赋值,但是可以取他的地址。左值引用就是给左值的引用,给左值取别名。

左值都是可以获取地址,基本都可以可以赋值
但const修饰的左值,只能获取地址,不能赋值。

右值?
右值也是一个数据的表达式,如字面常量,表达式返回值,传值返回的函数的返回值(不能是左值引用返回)。右值不能取地址,不能出现在赋值符号的左边。

关键看能不能取地址

给右值取别名就用右值引用,右值引用是左值了,放在赋值符号的左边了。

右值不能取地址,但是给右值引用后,引用的变量是可以取地址的,并且可以修改!
右值引用存放的地方在栈的附近。

int main()
{
	int&& rra = 10;
	//不想被修改 const int&& rra
	cout << &rra << endl;
	rra = 100;
	return 0;
}

左值引用总结:

  • 左值引用只能引用左值,不能引用右值。
  • 但是const修饰的左值引用既可以引用左值,又可以引用右值。在没有右值引用的时候就必须采用这种方式了。
  • 左值最重要的特征是都可以取地址,即使自定义类型也有默认的取地址重载。

右值引用总结:
右值引用只能引用右值,不能引用左值。
右值引用可以引用move以后的左值。

左值引用可以接着引用左值引用,右值引用不可以。
原因:右值引用放到左边表示他已经是一个左值了,右值引用不能引用左值!

int main()
{
	int a = 10;
	int& ra = a;
	int& rb = ra;
	int&& rra = 10;
	int&& rrb = rra;//err:无法从“int”转换为“int && "
	return 0;
}

匹配问题:

void func(const int& a)
{
	cout << "void func(const int& a)" << endl;
}

void func(int&& a)
{
	cout << "void func(int&& a)" << endl;
}

int main()
{
	int a = 10;
	func(10);
	func(a);
	return 0;
}

右值在有右值引用会去匹配右值引用版本!
在这里插入图片描述

右值真正的用法

本质上引用都是为了减少拷贝,提高效率。而左值引用解决了大部分的场景,但是左值引用在传值返回的时候比较吃力,由右值引用来间接解决。

左值引用在引用传参可以减少拷贝构造,但是返回值的时候避免不了要调用拷贝构造。

传参用左值拷贝和右值拷贝都一样,但是返回值如果用右值引用效率会高,并且通常左值引用面临着对象出了作用域销毁的问题。所以这就是右值引用的一个比较厉害的用法。

返回对象若出了作用域不存在,则用左值引用返回和右值引用返回都是错误的。

std::move是将对象的状态或者所有权从一个对象转移到另一个对象,只是转移,没有内存的搬迁或者内存拷贝,所以可以提高利用效率,改善性能。所以当作函数返回值的时候如果对象不存在左值引用和右值引用都会报错!

场景:返回的对象在局部域中栈上存在,返回该对象必须用传值返回,并且有返回对象接受,这个时候编译器优化,将两次拷贝构造优化成一次拷贝构造。

测试用的string类

#include<assert.h>
namespace ljh
{
	class string
	{
	public:
		typedef char* iterator;
		iterator begin()
		{
			return _str;
		}
		iterator end()
		{
			return _str + _size;
		}
		string(const char* str = "")
			:_size(strlen(str))
			, _capacity(_size)
		{
			//cout << "string(char* str)" << endl;
			_str = new char[_capacity + 1];
			strcpy(_str, str);
		}
		// s1.swap(s2)
		void swap(string& s)
		{
			::swap(_str, s._str);
			::swap(_size, s._size);
			::swap(_capacity, s._capacity);
		}
		// 拷贝构造
		string(const string& s)
			:_str(nullptr)
		{
			cout << "string(const string& s) -- 深拷贝" << endl;
			string tmp(s._str);
			swap(tmp);
		}
		// 赋值重载
		string& operator=(const string& s)
		{
			cout << "string& operator=(string s) -- 深拷贝" << endl;
			string tmp(s);
			swap(tmp);
			return *this;
		}
		// 移动构造
		/*string(string&& s)
			:_str(nullptr)
			, _size(0)
			, _capacity(0)
		{
			cout << "string(string&& s) -- 移动语义" << endl;
			swap(s);
		}*/
		// 移动赋值
		string& operator=(string&& s)
		{
			cout << "string& operator=(string&& s) -- 移动语义" << endl;
			swap(s);
			return *this;
		}
		~string()
		{
			delete[] _str;
			_str = nullptr;
		}
		char& operator[](size_t pos)
		{
			assert(pos < _size);
			return _str[pos];
		}
		void reserve(size_t n)
		{
			if (n > _capacity)
			{
				char* tmp = new char[n + 1];
				strcpy(tmp, _str);
				delete[] _str;
				_str = tmp;
				_capacity = n;
			}
		}
		void push_back(char ch)
		{
			if (_size >= _capacity)
			{
				size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;
				reserve(newcapacity);
			}
			++_size;
			_str[_size] = '\0';
		}
		//string operator+=(char ch)
		string& operator+=(char ch)
		{
			push_back(ch);
			return *this;
		}
		const char* c_str() const
		{
			return _str;
		}
	private:
		char* _str;
		size_t _size;
		size_t _capacity; // 不包含最后做标识的\0
	};
}

临时变量如果是4/8字节,通常在寄存器当中,但是如果是较大的内存,会在调用方的函数栈帧中开辟一块空间用于接受,这就是临时对象。

临时对象存在的必要性
当我们不需要接受返回值,而是对返回的对象进行直接使用,这个时候被调用的函数中的对象出了函数栈帧就销毁了,所以在栈帧销毁前会将对象拷贝到调用方栈帧的一块空间当中,我们可以用函数名对这个临时对象直接进行操作的(通常不能修改这个内存空间,临时变量具有常性)。

分析下面几组图片代码的效率

不可避免的,下面的这个过程必然要调用两次拷贝构造,编译器对于连续拷贝构造优化成不生成临时对象,由func::ss直接拷贝给main的str,我们如果只有前面所学的左值引用,func中的string ss在出了func后销毁,这个时候引用的空间被销毁会出现问题,这个时候显得特别无力。
在连续的构造+拷贝构造会被编译器进行优化,这个优化要看平台,但大部分平台都会做这个处理。
在这里插入图片描述
结果:在这里插入图片描述

即使下面这种情况,在main接受没有引用的情况下,依旧会调用一次拷贝构造,跟上面并没有起到一个优化的作用。
在这里插入图片描述
结果:在这里插入图片描述

解决方案:添加移动构造,添加一个右值引用版本的构造函数,构造函数内部讲s对象(将亡值)的内容直接跟要构造的对象交换,效率很高!!

string(string&& s)
		:_str(nullptr)
		, _size(0)
		, _capacity(0)
	{
		cout << "string(string&& s) -- 移动语义" << endl;
		swap(s);
	}

有了移动构造,对于上面的案例就变成了一次拷贝构造加一次移动构造。**编译器优化后将ss判断为将亡值,直接移动构造str对象,不产生临时对象了,就只是一次移动构造,效率升高!!**同理移动赋值!
在这里插入图片描述
结果:在这里插入图片描述

下面情况是引用+移动构造,但是编译器优化就会判断ss出了作用域还存在,反而会拿ss拷贝构造str,这个时候起不到优化的作用!
在这里插入图片描述
结果:在这里插入图片描述

以上采用将对象开辟在堆上或静态区都能够采用引用返回解决问题,但是有一个坏处?
引入多线程的概念,每个线程执行的函数当中若有大量的堆上的数据或者静态区的数据,相当于临界资源变多,要注意访问临界资源要加锁。而每个栈区私有栈,会相对好些

右值:
1、内置类型表达式的右值,纯右值。
2、自定义类型表达式的右值,将亡值。

将亡值:

string(string&& s)
			:_str(nullptr)
			, _size(0)
			, _capacity(0)
		{
			cout << "string(string&& s) -- 移动语义" << endl;
			swap(s);
		}
int main()
{
	ljh::string& str = func2();
	vector<ljh::string> v;
	v.push_back("1234656");//传进去的就是右值,是用"1234656"构造一个string对象传入,就是典型的将亡值
}

移动构造:
将亡值在出了生命周期就要销毁了,构造的时候可以将资源转移过要构造的对象,让将亡的对象指向NULL,相当于替它掌管资源。移动构造不能延续对象的生命周期,而是转移资源。且移动构造编译器不优化本质是一次拷贝构造+一次移动构造(从将亡值(此时返回值还是一个左值)给到临时变量),再有临时变量给到返回值接受对象(移动构造);
编译器优化做第一次优化,会将将亡值当作右值,此时要进行两次移动构造,编译器第二次优化,直接进行一次移动构造,去掉生成临时对象的环节。
只有需要深拷贝的场景,移动构造才有意义,跟拷贝构造一样,浅拷贝意义不大。

move的真正意义:
表示别人可以将这个资源进行转移走。

在这里插入图片描述

int main()
{
//为了防止这种情况,也要添加移动赋值。
	ljh::string str1;
	str1 = "123456";
}

在这里插入图片描述

c++11的算法swap的效率跟容器提供的swap效率一样了。
在这里插入图片描述
vector提供的插入的右值引用版本,就是优化了传右值情况,如果C++98则需要拷贝放入,而有右值就可以直接移动构造。两个接口的效率差不多。
大多数容器的插入接口都做了右值引用版本!!
在这里插入图片描述

完美转发

模板函数或者模板类用的&&即万能引用。
模板中的&&不代表右值引用,而是万能引用,其既能接收左值又能接收右值。模板的万能引用只是提供了能够接收同时接收左值引用和右值引用的能力。而forward才能将这种右值特性保持下去。

但是引用类型的唯一作用就是限制了接收的类型,后续使用中都退化成了左值,

此时右值在万能引用成为左值,可能会造成本身右值可以移动构造,却变成左值只能拷贝构造了。
Fun(std::forward<T>(t));才能够保证转发的时候值的特性

void Fun(int &x){ cout << "左值引用" << endl; }
void Fun(const int &x){ cout << "const 左值引用" << endl; }

void Fun(int &&x){ cout << "右值引用" << endl; }
void Fun(const int &&x){ cout << "const 右值引用" << endl; }
void Func(int x) {
 // ......
}

template<typename T>
void PerfectForward(T&& t) {
 Fun(t);
}

int main()
{
 PerfectForward(10);           // 右值
 int a;
 PerfectForward(a);            // 左值
 PerfectForward(std::move(a)); // 右值
 const int b = 8;
 PerfectForward(b);      // const 左值
 PerfectForward(std::move(b)); // const 右值
 return 0; }

默认成员函数

C++11 新增了两个:移动构造函数和移动赋值运算符重载。

现在有8个:构造函数,析构函数,拷贝构造,拷贝赋值,取地址,const取地址移动构造,移动赋值。

移动构造函数的默认生成的要求比较严格:
如果你没有自己实现移动构造函数,且没有实现析构函数 、拷贝构造、拷贝赋值重载都没有实现。那么编译器会自动生成一个默认移动构造。默认生成的移动构造函数,对于内置类型
成员会执行逐成员按字节拷贝,自定义类型成员,则需要看这个成员是否实现移动构造,如
实现了移动构造就调用移动构造没有实现就调用拷贝构造
如果你提供了移动构造或者移动赋值,编译器不会自动提供拷贝构造和拷贝赋值。
同理移动赋值。

即对于深拷贝的类,最好所有的构造,析构,拷贝,赋值重载,移动拷贝,移动赋值都写上。

总结

左值引用通常在传参和传返回值的过程中减少拷贝,这是利用左值引用的语法特性。一般做不到的部分,通常选择传参的时候传引用也可以解决,不通过返回值接受。
右值引用,一般是在深拷贝的类,实现移动构造和移动赋值,能够解决左值引用无法做到的传返回值的效率问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【C++】C++11语法之右值引用 的相关文章

  • 为什么使用abs()或fabs()而不是条件否定?

    在 C C 中 为什么要使用abs or fabs 不使用以下代码即可查找变量的绝对值 int absoluteValue value lt 0 value value 这与较低级别的指令较少有关吗 您提出的 有条件的abs 并不等于std
  • Qt - 无法让 lambda 工作[重复]

    这个问题在这里已经有答案了 我有以下功能 我想在其中修剪我的std set
  • 在 C++ 中分割大文件

    我正在尝试编写一个程序 该程序接受一个大文件 任何类型 并将其分成许多较小的 块 我想我已经有了基本的想法 但由于某种原因我无法创建超过 12 kb 的块大小 我知道谷歌等上有一些解决方案 但我更感兴趣的是了解这个限制的根源是什么 然后实际
  • try-catch 中未处理的异常

    try list from XElement e in d Descendants wix File where e Attribute Name Value Contains temp Name e Parent Parent Attri
  • std::map 和二叉搜索树

    我读过 std map 是使用二叉搜索树数据结构实现的 BST 是一种顺序数据结构 类似于数组中的元素 它将元素存储在 BST 节点中并按其顺序维护元素 例如如果元素小于节点 则将其存储在节点的左侧 如果元素大于节点 则将其存储在节点的右侧
  • ZLIB 解压缩

    我编写了一个小型应用程序 该应用程序应该解压缩以 gzip deflate 格式编码的数据 为了实现这一点 我使用 ZLIB 库 使用解压缩功能 问题是这个功能不起作用 换句话说 数据不是未压缩的 我在这里发布代码 int decompre
  • VS30063:您无权访问 https://dev.azure.com

    我正在尝试在 asp net core 2 1 mvc 应用程序中使用以下代码连接 Azure DevOps Uri orgUrl new Uri https dev azure com xxxxx String personalAcces
  • 为什么密码错误会导致“填充无效且无法删除”?

    我需要一些简单的字符串加密 所以我编写了以下代码 有很多 灵感 来自here http www codeproject com KB security DotNetCrypto aspx create and initialize a cr
  • C++11 函数局部静态 const 对象的线程安全初始化

    这个问题已在 C 98 上下文中提出 并在该上下文中得到回答 但没有明确说明有关 C 11 的内容 const some type create const thingy lock my lock some mutex static con
  • Xamarin Android:获取内存中的所有进程

    有没有办法读取所有进程 而不仅仅是正在运行的进程 如果我对 Android 的理解正确的话 一次只有一个进程在运行 其他所有进程都被冻结 后台进程被忽略 您可以使用以下代码片段获取当前正在运行的所有 Android 应用程序进程 Activ
  • gdb 在 docker 上立即退出“进程已完成,退出代码 1”或 lldb“数据包返回错误 8”。另外:如何在 docker 中允许进行 C++ 调试

    这花了我一整天的时间才找到 所以我将其发布以供将来参考 我正在 docker 镜像上开发 C 我正在使用克利翁 我的代码是在调试模式下编译的 并且在运行模式下运行良好 但是当尝试调试时 进程会立即退出 并显示非常丰富的信息 Process
  • 组合框项目为空但数据源已满

    将列表绑定到组合框后 其 dataSource Count 为 5 但组合框项目计数为 0 怎么会这样 我习惯了 Web 编程 而且这是在 Windows 窗体中进行的 所以不行combo DataBind 方法存在 这里的问题是 我试图以
  • 过期时自动重新填充缓存

    我当前缓存方法调用的结果 缓存代码遵循标准模式 如果存在 则使用缓存中的项目 否则计算结果 在返回之前将其缓存以供将来调用 我想保护客户端代码免受缓存未命中的影响 例如 当项目过期时 我正在考虑生成一个线程来等待缓存对象的生命周期 然后运行
  • 32位PPC rlwinm指令

    我在理解上有点困难rlwinmPPC 汇编指令 旋转左字立即然后与掩码 我正在尝试反转函数的这一部分 rlwinm r3 r3 0 28 28 我已经知道什么了r3 is r3在本例中是一个 4 字节整数 但我不确定这条指令到底是什么rlw
  • 无法使用 Ninject 将依赖项注入到从 Angular 服务调用的 ASP.NET Web API 控制器中

    我将 Ninject 与 ASP NET MVC 4 一起使用 我正在使用存储库 并希望进行构造函数注入以将存储库传递给其中一个控制器 这是实现 StatTracker 接口的上下文对象 EntityFramework public cla
  • 同时从多个流中捕获、最佳方法以及如何减少 CPU 使用率

    我目前正在编写一个应用程序 该应用程序将捕获大量 RTSP 流 在我的例子中为 12 个 并将其显示在 QT 小部件上 当我超过大约 6 7 个流时 问题就会出现 CPU 使用率激增并且出现明显的卡顿 我认为它不是 QT 绘制函数的原因是因
  • 如何查明CONFIG_FANOTIFY_ACCESS_PERMISSIONS是否启用?

    我想利用fanotify 7 http man7 org linux man pages man7 fanotify 7 html我遇到的问题是在某些内核上CONFIG FANOTIFY ACCESS PERMISSIONS不起作用 虽然C
  • Swagger 为 ASP.CORE 3 中的字典生成错误的 URL

    当从查询字符串中提取的模型将字典作为其属性之一时 Swagger 会生成不正确的 URL 如何告诉 Swagger 更改 URL 中字典的格式或手动定义输入参数模式而不自动生成 尝试使用 Swashbuckle 和 NSwag 控制器 pu
  • 如何确定母版页中正在显示哪个子页?

    我正在母版页上编写代码 我需要知道正在显示哪个子 内容 页面 我怎样才能以编程方式做到这一点 我用这个 string pageName this ContentPlaceHolder1 Page GetType FullName 它以 AS
  • WPF/数据集:如何通过 XAML 将相关表中的数据绑定到数据网格列中?

    我正在使用 WPF DataSet 连接到 SQL Server Express XAML 和 C Visual Studio 2013 Express 我从名为 BankNoteBook 的现有 SQL Server Express 数据

随机推荐

  • vue实现批量打印

  • 数据压缩实验之 H.264编解码实验

    文章目录 1 将两个 264文件进行解码 得到相应的YUV文件 2 将上述两个视频序列编码为 264文件 2 1 固定码率 以不同的GOP长度及形状编码 2 1 1 GOP 15 2B帧 2 1 2 GOP 12 2B帧 2 1 3 GOP
  • Golang三剑客之Pflag、Viper、Cobra

    如何构建应用框架 想知道如何构建应用框架 首先你要明白 一个应用框架包含哪些部分 在我看来 一个应用框架需要包含以下 3 个部分 命令行参数解析 主要用来解析命令行参数 这些命令行参数可以影响命令的运行效果 配置文件解析 一个大型应用 通常
  • Jupyter notebook的使用

    1 参考博客 https www cnblogs com nxld p 6088003 html 一 两种方式 1 启动cmd 然后输入命令 jupyter notebook 就可以直接调转到网页 因为这是在网页上直接运行的 2 一般启动程
  • 试题 B: 顺子日期

    问题描述 小明特别喜欢顺子 顺子指的就是连续的三个数字 123 456 等 顺子日 期指的就是在日期的 yyyymmdd 表示法中 存在任意连续的三位数是一个顺 子的日期 例如 20220123 就是一个顺子日期 因为它出现了一个顺子 12
  • Git代码拉取与同步

    1 git clone email protected xxx xxx git 2 git checkout b dev origin dev 创建本地dev分支 并与远程dev分支关联 3 git remote add upstream
  • 如何做单元测试

    如何做单元测试 一 定义 二 为什么要做单元测试 三 单元测试用例 四 阿里单元测试规约 五 测试框架的使用 Junit 下面以Junit4 为例来介绍 1 1 什么是Junit 1 2 为何使用Junit 1 3 Junit的快速入门 导
  • 学习笔记——SVG.js中形状元素的创建及其相关方法

    CreateElement 1 创建svg元素 在svg js中 每个元素都是一个对象 可以通过构造它来创建 import Rect from svgdotjs svg js var rect new Rect size 100 100 a
  • Unity3d中脚本无法编译问题(Monodevelop)

    使用Monodevelop打开脚本 编译时报错 具体错误忘记了 原因是 net框架引起 升级到 net框架4 5后解决
  • centos 7安装BBR加速报错:sysctl: setting key “net.ipv4.tcp_congestion_control“: 没有那个文件或目录的修复方法

    uname r 查看一下内核是什么版本 这个报错无非就是你内核不是4 9以上 从以下链接进去重启系统更新超过4 9内核就好 我升级后是5 14 成功运行 CentOS 7 启动 BBR 教程
  • 主成分分析R语言实现

    主成分分析是一种常见的降维统计方法 它通过适当的变量替换 使得新变量成为原变量的线性组合 并且新变量间彼此独立 从而可从错综复杂的关系中寻求主要成分信息 揭示变量内在关系 本次主要分享的是该方法的R语言实现 目录 数据集展示 一 计算相关系
  • win10安装mujoco150 , mujoco_py1.50.1.68 , gym

    win10安装mujoco mujoco py gym 本文介绍的是在Win10系统下安装gym mujoco150 mujoco py1 50 1 68的具体流程 另外一篇是安装mujoco200和mujoco py2 0 2 9版本 方
  • 爬虫超简化详细流程

    第一章 爬取网页源代码 一 导入模块 使用pip命令模块在电脑终端 下载基础爬取所用模块 requests import requests 二 放置网址 单引号中放置网址 url 三 设置请求头 headers Accept 辨识内容为全部
  • am335x+wm8960音频基于linux 4.9.41移植

    1 配置内核驱动 gt Device Drivers gt Sound card support SOUND y
  • IMX6学习记录(7)-编译脚本

    上面是我的微信和QQ群 欢迎新朋友的加入 1 效果 这几天搞这个东西 会有一大堆的命令行操作 很多重复的内容 现在做一个简单的脚本 方便自己平时的开发工作 2 脚本内容 bin bash uboot编译 function mk uboot
  • Django form组件

    form组件博客整理一 背景 我们之前在HTML页面中利用form表单向后端提交数据时 都会写一些获取用户输入的标签并且用form标签把它们包起来 与此同时我们在好多场景下都需要对用户的输入做校验 比如校验用户是否输入 输入的长度和格式等正
  • IDEA找不到程序包 和 request.getServletContext()报错Cannot resolve method ‘getServletContext()的解决方法

    重新装了idea和down了项目却一直报错 在调用request getServletContext 的方法时一直报Cannot resolve method getServletContext 的错误 网上查了好多方法 大多数都是在说是s
  • ModuleNotFoundError: No module named ‘tensorflow.contrib‘

    代码错误 Traceback most recent call last File D PyCharm PythonProject DRL Networking master DRL Networking master IPDPS2020
  • Android4.0 SDK功能详解

    我在eoe的论坛找到的 就复制过来了 跟大家分享一下 Android 4 0 平台API等级 14 Android 4 0 是一次重要的平台发布版 为用户和应用程序开发者增加了大量的新特性 在下面我们将讨论的所有新特性和API中 因为它将
  • 【C++】C++11语法之右值引用

    文章目录 一 的扩展 initializer list的讲解 二 C 11一些小的更新 decltype nullptr 范围for 新容器 三 右值引用 右值真正的用法 完美转发 默认成员函数 总结 一 的扩展 在原先c 的基础上 C 1