当前位置: 首页 > news >正文

免费关键词挖掘网站开发小程序需要多少钱费用

免费关键词挖掘网站,开发小程序需要多少钱费用,网站开发维护费用,海口公司网站建设目录 1.什么是衰退复制#xff08;decay-copy#xff09; 1.1.推导规则 1.2.LWG issue 929 1.3.想象中的 decay_copy 2.decay-copy 与 auto 2.1.为什么引入衰退复制 2.2. 成为 C 23 的语言特性 3.应用场景 4.总结 1.什么是衰退复制#xff08;decay-copy#xff0…目录 1.什么是衰退复制decay-copy 1.1.推导规则 1.2.LWG issue 929 1.3.想象中的 decay_copy 2.decay-copy 与 auto 2.1.为什么引入衰退复制 2.2. 成为 C 23 的语言特性 3.应用场景 4.总结 1.什么是衰退复制decay-copy 1.1.推导规则 要理解为什么 C 会有衰退复制decay-copy这个需求需要了解一下 LWG issue 929 问题的提出但是要理解这个 issue最好先复习一下 C 模板参数的推导规则。我们按照模板的形参类型进行以下分类大致可分为三类不讨论 auto 的推导 形参类型基本规则 非转发引用类型的引用 :          templatetypename T void f(T param); f(expr); 忽略实参表达式中的引用将实参表达式 expr 与 param 做模式匹配确定 T 的类型 转发引用: templatetypename T void f(T param); f(expr); 如果 expr 是类型 E 的左值则 T 被推导为 E经过引用折叠后将 param 的类型生成为 E。对于其他情况按照普通引用的规则推导前面一条。 传值参数: templatetypename T void f(T param); f(expr); 如果 expr 的类型是引用类型则忽略引用 如果 expr 表达式含有 CV 限定则忽略 CV 限定 然后与 param 做模式匹配确定 T 的类型。 重点类型退化 我们不讨论 auto 的推导规则也不考虑形参表达式与实参表达式的模式匹配的细节上表是类型推导的基本规则其中重点是传值参数的类型退化。退化主要有两点就是数组类型会在推导前退化成指针函数类型也会在推导前退化成函数指针。当形参类型是引用类型的时候不会发生退化这就是为什么如果我们希望推导类型是数组类型就只能使用引用类型的原因。 1.2.LWG issue 929 在制定 C 11 标准的过程中C 标准委员会的标准库工作组Library Working Group收到一个 Issue就是这个LWG issue 929 [资料 1]。C 11 新增了对并发concurrency support library的支持但是在使用普通函数构造线程的时候会遇到一些麻烦比如这段代码 void f(const char*); std::thread t(f,hello); std::thread 的构造函数使用右值引用传递可调用物和可调用物的参数并且要求可调用物对应的参数支持可复制构造CopyConstructible特性。这样的约束过于严格限制是使用普通函数作为可调用物的可能性。因为在 std::thread 的构造函数函数模板参数推导过程中因为参数类型使用了右值引用则绑定的参数类型会被推导为函数的引用类型而不是退化为函数指针。 于此同时对参数类型使用右值引用也阻止了从数组到指针的退化。由于数组不可复制不可移动所以结果就是阻止了数组作为可调用物的参数使用的可能性。在这个例子中字符串字面量会被推导为 const char[6] 类型显然与 const char * 是不匹配的这就也阻止了在这种情况下使用字符串字面量的可能。 如果将 std::thread 的构造函数的参数改成传值类型数组可以退化成指针就消除了要求数组具备可复制构造的矛盾。但是传值参数会引起参数传递的效率问题可见问题没有这么简单。 1.3.想象中的 decay_copy 既然不能简单使用传值参数那么可不可以在参数推导的时候做点手动退化呢当然可以LWG issue 929 建议引入一个类似这样的 decay_copy() 函数 templatetypename T typename decayT::type decay_copy(T v); 以便得到一个 v 的右值副本用于右值引用类型的传递。有了 decay_copy() 函数你可以将标准库中 std::thread 的构造函数大致理解为这样的实现 template class Function, class Arg thread(Function f, Arg arg) {std::invoke(std::decay_copy(std::forwardFunction(f)),std::decay_copy(std::forwardArg(arg))); } decay_copy() 函数可以将参数拷贝或移动到参数类型的退化版本的副本上与此同时带来的后果就是当你真的需要传递引用的时候你需要用 C 的引用包装器std::ref 和 std::cref来对抗这种退化。 好吧必需得承认上面的 decay_copy() 函数是我们的想象C 只是引入了衰退复制的概念但是并没有在库中添加这个函数。至于为什么引入这个概念以及最后到底怎么实现了这个概念请继续看下去。 2.decay-copy 与 auto 2.1.为什么引入衰退复制 C 11 引入衰退复制的目的仅仅是为了满足并发库的特殊兴趣爱好吗当然不是衰退复制其实是一种具体使用场景的需求一句话描述这个场景就是当你需要传递一个对象的副本拷贝给一个操作但是这个操作只接受对象的引用。在这种情况下如果我们传递的是左值类型的副本就必需小心维护这个副本的生命周期否则很可能会发生引用悬挂如果传递的是右值副本则可以通过绑定到右值引用而延长生命周期避免引用悬挂会相对比较安全。 根据第 1 节的介绍我们其实已经知道所谓的衰退复制其实就是得到对象的一个纯右值副本。LWG issue 929 建议增加一个 decay_copy() 函数但是并没有被 C 标准采纳。以下是很多资料中都提到的这个函数的具体实现 templateclass T constexpr std::decay_tT decay_copy(T v) noexcept(std::is_nothrow_convertible_vT, std::decay_tT) {return std::forwardT(v); } 很多情况下我们可以显式使用 decay_copy() 函数达到我们的目的。比如这个例子 void ProcessFoo(Foo f);Foo foo{ 42 };ProcessFoo(foo); //错误foo 是左值 ProcessFoo(std::move(foo)); // 可以但是慎重 ProcessFoo(decay_copy(foo)); //OKfoo 还活着 在这个例子中使用 move 可以满足函数调用的要求但是要慎重在某些场合 foo 可能会真的被移走这可能不是我们希望的结果。使用 decay_copy() 就放心多了通过函数返回值得到一个纯右值副本也不需要关心它的生命周期维护问题。 衰退复制的思想在线程库、ranges 库大量使用在一些异步调用的过程中以及变量需要被延迟绑定的场合也会需要这个概念。 2.2. 成为 C 23 的语言特性 为什么标准库不要 decay_copy() 函数上面给了这样一个例子 class A {int x;public:A();auto run() {f(A(*this)); // okf(auto(*this)); // ok as proposedf(decay_copy(*this)); // ill-formed}protected:A(const A); }; 要拿到一个对象的副本需要能直接访问对象的拷贝构造函数或移动构造函数对于这个例子因为 decay_copy() 函数不是 A 的友元函数无法访问 A 的构造函数这就限制了 decay_copy() 函数的使用毕竟标准库也不可能把这个函数声明成任何对象的友元。 从 C 11 开始auto 关键字就一直是个多才多艺的家伙从自动推导类型占位符到 C 20 的模板化 lambda 表达式auto 关键字的出镜率极高。尽管如此还有两个表达形式没有被用到那就是独立的 auto(x) 和 auto{x} 表达式。既然闲着就拉来加个班吧于是用 auto 做纯右值副本成了 C 23 的语言特性。用 auto(x) 或 auto{x}  代替 decay_copy() 函数不仅仅是查找替换这么简单auto 有更好的性能。 decay_copy() 函数无论如何都会产生一个对象副本但是 auto(x) 更智能一点如果 x 本身就是一个纯右值的话auto(x) 不做任何操作不产生开销。对于上一节的 ProcessFoo() 函数用 auto(x) 代替 decay_copy() 函数 ProcessFoo(auto(foo)); // OK ProcessFoo(auto{foo}); // OK 可能有人会想已知对象类型是 T 直接 T() 或 T{} 构造一个对象副本不行吗为什么还要增加这个语言特性首先直接构造对象副本存在与 decay_copy() 函数一样的问题那就是要解决拷贝构造函数或移动构造函数的可访问性还有就是无论如何都产生副本的操作在 x 本身是右值的情况下有点多余这是性能问题。其次是在一些泛型编程或模板库中T 的具体类型不是那么具体比如这个例子 void pop_front_alike(Container auto x) {std::erase(x.begin(), x.end(), auto(x.front())); } auto(x.front()) 可以轻松得到一个 x.front() 的右值副本如果尝试直接调用构造函数就会麻烦很多 void pop_front_alike(Container auto x) {using T std::decay_tdecltype(x.front());std::erase(x.begin(), x.end(), T(x.front())); } 首先要用 decltype 得到 x.front() 返回值的类型然后还要手动退化一下因为得到的类型可能是引用类型或者有 CV 限定。这么做不如 auto 语言特性来的直接并且如果容器 Container 的 front() 返回类型本身就是右值这里用 auto 就不会产生任何开销。 3.应用场景 1) 模板参数推导         在模板编程中当模板函数的参数类型与传入的实参类型不匹配时编译器会根据一系列推导规则来确定模板参数的具体类型。这个过程中可能会发生衰退复制特别是当实参是数组或函数类型时它们可能会被推导为相应的指针类型。 C之std::decay 2) 并发编程中的线程构造         在C11及以后的标准中引入了并发编程的支持包括线程std::thread等。当使用std::thread构造函数创建线程时需要传递一个可调用对象如函数、函数对象、lambda表达式等及其参数。如果传递的参数类型与std::thread构造函数期望的参数类型不匹配则可能会发生衰退复制。 std::thread使用及实现原理精讲(全)-CSDN博客 4.总结 C中的衰退复制是一个与类型推导和参数传递相关的复杂过程。在编写C代码时需要仔细考虑类型匹配和参数传递方式以避免不必要的衰退复制和潜在的类型错误。 从 C 23 开始标准库中原来使用的类似 decay_copy() 函数那样的表达形式都被 auto(x) 取代在某些情况下得到了性能提升。
http://www.w-s-a.com/news/396638/

相关文章:

  • 为什么学网站开发凡科登陆
  • 设计师常备设计网站大全中山精品网站建设信息
  • 杭州建设工程网seo服务是什么
  • 兼职做问卷调查的网站wordpress mysql设置
  • 怎么在百度上能搜到自己的网站山西seo谷歌关键词优化工具
  • 网站搭建免费模板飞鱼crm下载
  • 网站开发竞品分析app制作公司深圳
  • 网站建设ssc源码修复设计班级网站建设
  • 网站重定向凡科做网站不要钱
  • 佛山html5网站建设微信营销软件破解版
  • 网站单页做301南京百度推广
  • 私人做网站要多少钱展芒设计网页
  • 怎样网站制作设计如何在网上推广农产品
  • 做关键词排名卖网站聚名网
  • 吉林省住房城乡建设厅网站首页体育器材网站建设方案
  • 网站建设及维护专业手机金融界网站
  • 常州网站建设工作室建立网站有怎么用途
  • 如何盗取网站推广策划书模板
  • 游戏网站建设计划书网络开发需要学什么
  • 手机网站维护费网站开发包括网站过程
  • 懂做游戏钓鱼网站的网站建设技术的发展
  • 网站被百度收录百度一下你就知道 官网
  • 雅客网站建设做网站用什么做
  • 做宣传海报网站专业网站设计速寻亿企邦
  • 秦皇岛市住房和城乡建设局网站有关网站开发的参考文献
  • 晋城城乡建设局网站深圳外贸业务员工资
  • 招聘网站开发的公司销售运营主要做什么
  • 徐州网站无障碍建设wordpress证书
  • c语言可以做网站吗请人做网站收费多少
  • 中英双语网站怎么做网站为什么做静态