首页
学习
活动
专区
圈层
工具
发布

Chapter 5: Rvalue References, Move Semantics, PF

std::forward的作用是当我们传入的参数是左值时,在内部将参数转发到其他函数时仍然是按照左值转发(也就是调用左值参数的函数),而当是右值时按照右值转发(调用右值参数的函数);仅当传入的参数被一个右值初始化过后...这样它就会产生许许多多的参数类型的重载实例函数。 在编译器为类自动生成移动和拷贝构造函数时,也不能使用重载过的通用引用参数构造函数,因为通用引用参数的构造函数在匹配顺序上会在其他重载函数之前。...如果对传入的对象p加上const修饰,那么虽然模板函数虽然会被实例化成为一个接收const类型Person对象的函数,但是具有在const类型参数的所有重载函数中,C++中的重载解析规则是:当模板实例函数和非模板函数同样都能匹配一个函数调用...Understand reference collapsing 当模板函数的参数是一个通用引用参数时,当一个参数传递给这个模板函数,模板参数推导的类型才会编码这个参数是左值还是右值。...编码机制是:当传递的参数是一个左值时,模板参数被推导为左值引用;当传递的参数是一个右值时,模板参数被推到为一个非引用。

5.5K40
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    C++那些事之SFINAE

    overload resolution, SFINAE and the static behavior of sizeof 2.1重载决议 当一个函数名称和某个函数模板名称匹配时,重载决议过程大致如下:...2.2 SFINAE 回忆一下上述的重载决议: 函数调用 函数模板 SFINAE 我已经用几个段落的强大功能来戏弄你了,现在终于可以解释这个并不复杂的缩写词了。...我带给您难题的最后一部分,称为enable_if。 如您所见,我们可以使用enable if根据编译时表达式触发替换失败。...如您所见,auto允许使用尾随返回类型语法,并使用decltype以及涉及函数参数之一的表达式。这是否意味着我们可以使用它来测试SFINAE序列化的存在? 是的,沃森博士!...在decltype中,将评估所有表达式,但仅将最后一个表达式视为该类型。序列化不需要任何更改,减去了STL中现在提供了enable_if函数的事实。

    2.9K20

    现代C++之SFINAE

    overload resolution, SFINAE and the static behavior of sizeof 2.1重载决议 当一个函数名称和某个函数模板名称匹配时,重载决议过程大致如下:...2.2 SFINAE 回忆一下上述的重载决议: 函数调用 函数模板 SFINAE 我已经用几个段落的强大功能来戏弄你了,现在终于可以解释这个并不复杂的缩写词了。...我带给您难题的最后一部分,称为enable_if。 如您所见,我们可以使用enable if根据编译时表达式触发替换失败。...如您所见,auto允许使用尾随返回类型语法,并使用decltype以及涉及函数参数之一的表达式。这是否意味着我们可以使用它来测试SFINAE序列化的存在? 是的,沃森博士!...在decltype中,将评估所有表达式,但仅将最后一个表达式视为该类型。序列化不需要任何更改,减去了STL中现在提供了enable_if函数的事实。

    3.6K20

    C++11相较于C++98的核心提升与实现原理深度解析

    []{ return ready; })通过“原子操作序列”避免虚假唤醒:首先释放互斥量lk,使其他线程可获取锁并修改条件;随后阻塞等待通知;被唤醒后重新获取互斥量,并检查条件谓词ready是否满足,仅当条件为真时才继续执行...Failure Is Not An Error,替换失败并非错误)机制在编译期筛选重载函数:当模板参数T为整数类型时,std::is_integral\::value为true,std::enable_if...An Error,替换失败并非错误)机制在编译期筛选重载函数:当模板参数T为整数类型时,std::is_integral::value为true,std::enable_if的type成员被定义为...这种机制使得开发者能够根据类型属性实现函数的条件化重载,例如:// 仅当T为整数类型时启用此重载template typename std::enable_if::value, void>::typeprint(T value) { std::cout 仅当T为浮点数类型时启用此重载

    32700

    模板进阶

    bool Less(Date* left, Date* right) { return *left < *right; } 三者都存在时,编译器会优先走函数重载,因为函数重载是直接能用的,比函数模板特化更加现成...偏特化优先于通用模板: 若参数部分匹配偏特化的条件,优先选择偏特化。 通用模板是最后选择: 仅当无特化版本匹配时,才会使用通用模板。...运行时动态性受限 编译时确定类型: 模板的类型必须在编译时确定,无法实现真正的运行时多态(需结合虚函数或类型擦除技术如 std::any)。 三、使用场景与替代方案 1....编译时逻辑优化(如条件编译、静态检查)。 2. 替代方案 运行时多态(虚函数): 适用于需要动态类型或接口统一的场景,但会引入运行时开销。...在性能关键型项目和泛型库开发中,模板几乎是不可替代的工具;而在需要动态多态或快速迭代的场景中,需谨慎选择其使用范围。

    11910

    【C++11】消除重复, 提升代码质量---type_tratis

    ,不能直接确定函数返回类型; 通过decltype推导函数返回类型时可读性差问题; 使用后置推导类型时,如果没有构造函数导致编译报错的问题; std::result_of原型如下: template 当匹配到void Fun(T*)时用整数对T*进行替换是错误的,但是编译器会继续匹配,直到匹配到void Fun(T)后执行正确的函数,这种规则就是SFINAE;反之,如果一个模板函数都没有匹配到...,则编译器会报如下错误: error: no matching function for call to 'Fun(int)' std::enable_if实现了根据条件选择重载函数的规则,其原型如下:...主要用作函数返回值,同时它还可以用来限定模板定义模板特化和入参类型限定。...因此,它可以在编译期间检查模板参数是否有效。使用std::enable_if可以实现一个强大的重载机制,充分利用可以减少或者消除圈的复杂度。如:根据不同的数据基本类型转换为string进行输出。

    2.1K10

    浅谈 C++ 元编程

    在标准库中,容器 (container) 和 函数 都是 类模板 和 函数模板 的应用。...转化为常量表达式,类似测试表达式实现重载的选择(但需要添加一个冗余的 函数参数/函数返回值/模板参数); std::void_t 直接 检查依赖 的成员/函数是否存在,不存在则无法重载(可以用于构造谓词...然后根据 SFINAE 规则: 使用 std::enable_if 重载函数 ToString,分别对应了数值、C 风格字符串和非法类型; 在前两个重载中: 分别调用 std::to_string 和...2.2.1 定长模板的迭代 代码展示了如何使用 编译时迭代 实现编译时计算阶乘(N!)。函数 _Factor 有两个重载:一个是对任意非负整数的,一个是对 0 为参数的。...(Σ) 2.2.3 使用折叠表达式化简编译时迭代 在 C++ 11 引入变长模板时,就支持了在模板内直接展开参数包的语法;但该语法仅支持对参数包里的每个参数进行 一元操作 (unary operation

    3.8K61

    现代C++之SFINAE应用(小工具编写)

    现代C++之SFINAE应用(小工具编写) 0.导语 现在考虑这个输入: map mp{ {1, 1}, {2, 4}, {3, 9}...2.是否存在输出函数 使用SFINAE来检测是否可以直接输出: // 检测是否可以直接输出 template struct has_output_function { template...,也就是第一个函数在std::declval() 重载函数,发现后面还有个output函数,最后决议不报错,这便是SFINAE...3.针对没有输出函数的容器处理 通过enable_if_t限定调用重载操作符是针对没有输出函数的容器,内部逻辑很简单,第一次只输出元素,后面就输出,与元素,也就是用,分割元素,最后就是比较重要的output_element...下面原理还是SFINAE来实现的,当不是pair的时候就调用第二个重载函数了,否则就是第一个。

    1.5K20

    诡异!std::bind in std::bind 编译失败

    由于函数模板不能偏特化,所以引入了模板类,也就是上面的class _Mu。该类模板用于转换绑定参数,在需要的时候进行替换或者调用。...在方案二中,使用static_cast进行类型转换的方式,来解决编译报错问题,不妨以此为突破点,只有在std::is_bind_expression::value == TRUE的时候,才需要此类转换...为了分析该问题,私下跟提问的同学进行了友好交流,才发现他某个函数是重载的,而该重载函数的参数为参数个数和类型不同的std::function(),下面是简化后的代码: #include 函数中的fun()调用显然都匹配两个重载的fun()函数...好了,既然知道原因了,那就需要有解决办法,一般有如下几种: • 使用lambda替代std::bind() • 静态类型转换,即上一节中的static_cast ,转换成需要的类型 今天的文章就到这,我们下期见

    1.4K20

    C++20初体验——concepts

    简单需求 任意不以requires关键词开头的表达式都可以作为简单需求,当该表达式语法正确时需求满足。由于参数列表中的变量不实际存在,这个表达式当然也不会被求值。...requires (T a, T b) { a + b; } 类型需求 typename后跟一个类型名成为类型需求,当该类型存在时需求满足。类型需求可以用来检查嵌套类型和模板实例化。...requires后跟一个bool常量成为一个requires子句,仅当该bool常量的值为true时,子句所在的需求被满足,或所在的模板有效。...如果模板参数代入时出现了不存在的类型或变量,该约束仅仅是不被满足,而不会产生编译错误。 约束可以用于函数模板、类模板和成员函数,非模板类的非模板成员函数除外。...函数模板与类模板的约束是类似的,只有满足约束时模板才能实例化;对于成员函数的约束,如果它作用于模板类的模板参数,当约束不满足时,并不是类模板不能被实例化,而是实例化后的模板类没有这个成员函数: #include

    1.9K10

    C++11:利用模板简化重载右值引用参数的函数

    左值引用版本和右值引用版本的函数 下面是matrix_cl类的两个重载的构造函数,这两个构造函数除了最后一个参数不同,其他的参数都完全一样,只有最后一个参数不同(分别为右值和左值引用)。...当调用该构造函数时,如果最后一个参数为右值引用的时候,会优先调用第一个构造函数,使用移动语义std:move()将rv转为右值,将rv的内容赋值给this->v,这时调用的是std::vector的移动赋值操作符...&>::value // 模板常量参数,用于判断v是否为右值引用 ,typename _ENABLE=typename std::enable_if<std::is_base_of<std::vector...std::move(v):v; }; 有了_ENABLE进行参数类型限制,在类中有多个类型的模板构造函数的情况,调用构造函数时就不会将别的类型的参数误传入,而产生编译错误。...这里用到的std::enable_if,std::is_base_of,std::decay都是定义在#include中的模板函数,详细说明请打开链接查看。

    1.2K10

    C++11:unique_ptr 自己定义类似make_shared的make_unique模板函数

    C++11中的智能指针分为共享型的shared_ptr和独占型的unique_ptr,C++11提供了make_shared函数来创建shared_ptr指针,使用起来更方便,有了make_shared...模板参数中增加了一个常量参数ZERO,用于编译期判断。...用到了名为std::enable_if的type_traits,它类似一个if语句,判断ZERO,当ZERO为true时编译器选择第一个版本的函数,反之选择第二个。...,但是却与C++14版本的make_unique在模板参数类型上并不兼容,你为啥知道C++14的make_unique版本是什么样呢?....) = delete; 对这么简单的函数VS2015不可能写一个与标准不兼容的,所以如果考虑到与未来的C++14的兼容性,应该使用这个版本。 参照msvc版本代码修改如下: #if !

    1.4K20

    C++核心准则T.48:如果你的编译器不支持concepts,使用enable_if模仿它

    T.48: If your compiler does not support concepts, fake them with enable_if T.48:如果你的编译器不支持concepts,使用...enable_if模仿它 Reason(原因) Because that's the best we can do without direct concept support. enable_if can...因为这是不能活动concept的直接支持时可以采用的最佳做法。enable_if可以用于有条件定义函数并从一组函数中进行选择。...使用enable_if模拟概念重载有时会要求我们使用容易出错的设计技术。 Enforcement(实施建议) ??...这样一方面可以使读者了解真实的软件开发工作中每个设计模式的运用场景和想要解决的问题;另一方面通过对这些问题的解决过程进行说明,让读者明白在编写代码时如何判断使用设计模式的利弊,并合理运用设计模式。

    55330

    现代C++零基础到工程实战

    C++ 是一门兼具高性能与灵活性的系统级编程语言,广泛应用于游戏开发、嵌入式系统、高频交易、操作系统等领域。要系统掌握 C++,需从基础语法到高级特性逐步深入,并结合实践与底层原理。...内容:模板与泛型编程:函数模板、类模板。模板特化与偏特化。可变参数模板(std::tuple)。...内存与资源管理智能指针:避免手动 new/delete,使用 std::unique_ptr 和 std::shared_ptr。RAII 原则:通过构造函数/析构函数管理资源(如文件句柄、锁)。...模板元编程(TMP)编译期计算:通过 constexpr 和模板实现类型推导。CRTP 模式:利用继承实现静态多态(如 std::iterator)。SFINAE 技术:根据类型特性选择重载函数。...三、学习建议与避坑指南避免过度使用宏:优先使用 constexpr 和模板替代宏。慎用多重继承:优先通过组合(Composition)实现功能。关注异常安全:设计异常安全的代码(基本保证/强保证)。

    32610
    领券