首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么通过显式不可移动和隐式不可复制类型的值返回向量不会产生编译错误?

通过显式不可移动和隐式不可复制类型的值返回向量不会产生编译错误的原因是,向量的返回操作实际上会调用移动构造函数或移动赋值运算符,而不是复制构造函数或复制赋值运算符。

在C++中,显式不可移动类型是指具有显式定义的移动构造函数或移动赋值运算符的类型。这些操作符告诉编译器如何将对象的资源从一个对象转移到另一个对象,而不是进行复制操作。隐式不可复制类型是指具有删除的复制构造函数或复制赋值运算符的类型,这意味着编译器禁止对该类型进行复制操作。

当返回一个向量时,如果向量的元素类型是显式不可移动和隐式不可复制类型,编译器会尝试调用移动构造函数或移动赋值运算符来将向量从函数的局部变量移动到返回值。由于这些类型不可复制,编译器不会尝试调用复制构造函数或复制赋值运算符,因此不会产生编译错误。

然而,需要注意的是,如果向量的元素类型是显式可移动或隐式可复制类型,编译器将尝试调用复制构造函数或复制赋值运算符来复制向量,而不是移动它。如果这些操作被删除或不可用,则会导致编译错误。

总结起来,通过显式不可移动和隐式不可复制类型的值返回向量不会产生编译错误,是因为编译器会调用移动构造函数或移动赋值运算符来移动向量,而不是复制它。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

C ++ 中不容忽视的 25 个 API 错误设计!

因此,在我们的例子中,如果要使类不可复制和不可移动,我们将标记移动构造函数和movbe赋值操作符为已删除。...因此,如果你的类只包含简单的数据类型,并且你计划使用隐式生成的移动构造函数,那么如果你定义复制构造函数则不可能。在这种情况下时,你必须显式定义移动构造函数。...错误#6:不将单个参数构造函数标记为显式 为什么这是一个API设计错误? 允许编译器进行一次隐式转换以将参数解析为函数。...,因为现在编译器不会将第一个参数的类型强制为显式向量对象。...错误#8:通过const引用返回API的内部 为什么这是一个错误? 从表面上看,通过const引用返回一个对象似乎是双赢的。这是因为: 避免不必要的复制。

1.6K20
  • 每个C++开发者都应该学习和使用的C++11特性

    NULL 和 0 都可以隐式地转换为整数类型,可能引入一些不符合预期的行为。 为了解决这些问题,C++11 引入了 nullptr,它是一个明确的空指针常量,不具有整数类型,可以显式地表示空指针。...C++11中提供了三种主要的智能指针: std::unique_ptr: 独占所有权的智能指针。它不能被复制,但可以被移动。当指针超出作用域或被显式释放时,它所管理的资源将被释放。...对于大型对象或对象包含动态分配的资源,这种复制操作可能会导致昂贵的性能开销,尤其是在函数参数传递和返回值返回时。 2....通过右值引用,可以识别出临时对象,并且在这些对象上应用移动语义。 移动语义允许将资源从一个对象转移到另一个对象,而不是复制资源。...std::vector vec; vec.push_back("example"); // 移动临时对象 在函数返回值中使用: 当函数返回一个临时对象时,可以通过移动语义避免不必要的复制

    7810

    SystemVerilog(七)-网络

    工程师在使用网络类型时需要小心避免编码错误。网络列表中的简单错误可能会导致同一网络无意中连接到多个驱动程序。在编译和优化过程中不会捕获这种类型的错误。该错误会导致在仿真过程中检测到功能性错误。...这些建模错误在SystemVerilog中是合法的,因为网络类型允许多个驱动程序。 通过将输入端口显式声明为var logic类型,可以防止输入端口的意外多个驱动程序。变量不允许多个驱动源。...网络可以用与变量相同的方式显式声明为有符号或无符号。 网络位和部分选择。可使用与变量向量相同的语法从向量中选择任何特定位或位组。常量和变量位和部分选择都可以在网络上执行。...隐式网络可以减少编写网表模型所需的时间,并减少键入错误。 但是,隐式网络的一个缺点是,与模块、接口或例化实例的连接中拼写错误的名称不会被检测为连接错误。...这就要求显式声明所有网络,禁用隐式网络是通过设置编译器指令来完成的: 此编译器指令必须在模块外部设置,并对编译到同一编译单元的所有后续模块保持有效,或者直到遇到另一个'default_nettype指令

    1.5K40

    《Rust避坑式入门》第1章:挖数据竞争大坑的滥用可变性

    在某些情况下可能需要显式处理 () 值。 Unit类型可以用于表达主要执行副作用的函数的返回值,如 println!的返回值。可以用于实现 trait 方法时,方法不需要返回值。...另一个区别在于第一个参数,方法的 self 参数在定义时是显式的,但在调用时是隐式传递的。函数没有这个特殊的第一个参数。...&self 表示这是一个不可变的引用方法,不会修改 Theater 实例。-> i32 指定方法返回一个 i32 类型的值(票数)。...对于函数或方法,如果最后一个表达式不带分号,它就会成为该函数或方法的返回值。在 Rust 中,这是一种常见的隐式返回方式。...这里*self.available_tickets 作为最后一个不带分号的表达式,被隐式地用作代码块,进而作为get_available_tickets方法的返回值。

    56773

    第4章 | 移动

    ——译者注 4.2 移动 在 Rust 中,对大多数类型来说,像为变量赋值、将其传给函数或从函数返回这样的操作都不会复制值,而是会移动值。...但与 C++ 一样,所有权始终是明确的:程序不需要引用计数或垃圾回收就能知道何时释放向量元素和字符串内容。 代价是如果需要同时访问它们,就必须显式地要求复制。...之前我们谨慎地说过,大多数类型会被移动,现在该谈谈例外情况了,即那些被 Rust 指定成 Copy 类型的类型。对 Copy 类型的值进行赋值会复制这个值,而不会移动它。...只有那些可以通过简单地复制位来复制其值的类型才能作为 Copy 类型。前面解释过,String 不是 Copy 类型,因为它拥有从堆中分配的缓冲区。...这确实意味着 C++ 类可以提供 Rust 类型所无法提供的便捷接口,比如可以在看似普通的代码中隐式调整引用计数、把昂贵的复制操作留待以后进行,或使用另一些复杂的实现技巧。

    7710

    你不知道的JavaScript(中卷)一

    应该使用a.charAt(1)取下标位置的字符 3.字符串不可变是指字符串的成员函数不会改变其原始值,而是创建并返回一个新的字符串。...四、强制类型转换 A.值类型转换 1.将值从一种类型转换为另一种类型通常称为类型转换(type casting),这是显式的情况;隐式的情况称为强制类型转换(coercion) 2.JS中的强制类型转换总是返回标量基本类型值...,如字符串、数字和布尔值,不会返回对象和函数;“封装”,就是为标量基本类型值封装一个相应类型的对象,但这并非严格意义上的强制类型转换 3.类型转换发生在静态类型语言的编译阶段,而强制类型转换则发生在动态类型语言的运行时...,允许从符号到字符串的显式强制类型转换,然而隐式强制类型转换会产生错误。...• 符号不能够被强制类型转换为数字(显式和隐式都会产生错误),但可以被强制类型转换为布尔值(显式和隐式都是true) E.宽松相等和严格相等 1.

    1.2K20

    【笔记】《C++Primer》—— 第10章:泛型算法

    关于捕获变量,lambda有值捕获,引用捕获,隐式捕获三种类型。...其中值捕获和引用捕获区别就是写入捕获列表的名称是否加上引用符而已,效果也与引用变量相同 隐式捕获比较特别,通过在捕获列表中无名地写个=或&,可以告诉编译器推断函数所需要的捕获,其中=是值捕获推断,&是引用捕获推断...两种隐式捕获不能简单混用,如果声明了一种隐式捕获,那么剩余的只能用显式的传统的捕获,且显式捕获的类型还要和隐式捕获的不同,而且隐式捕获必须排列在显式捕获的前面 int main() {...auto lam2 = [&] {return a; }; // 混合捕获a(隐式的值捕获),b(显式的引用捕获) auto lam3 = [=, &b...{return a; }; 当lambda函数体中存在不止一句return时,编译器将假定返回类型为void,此时要通过第六章讲到的尾置返回来指定所需的返回类型 // 尾置返回指定 auto lam1

    66720

    挑逗 Java 程序员的那些 Scala 绝技

    Java 的优势在于它的类型可读性,如果显式声明了 userId 的类型,虽然还是可以正常通过编译,但是在代码审查时,这个错误将会更容易被发现。...我们可以通过显式或隐式方式传入一个线程池,具体的执行过程由线程池完成。...九、隐式参数和隐式转换 挑逗指数: 五星 隐式参数 如果每当要执行异步任务时,都需要显式传入线程池参数,你会不会觉得很烦?Scala 通过隐式参数为你解除这个烦恼。...如果 Scala 在编译时发现了错误,在报错之前,会先对错误代码应用隐式转换规则,如果在应用规则之后可以使得其通过编译,则表示成功地完成了一次隐式转换。...在不同的库间实现无缝对接 当传入的参数类型和目标类型不匹配时,编译器会尝试隐式转换。利用这个功能,我们将已有的数据类型无缝对接到三方库上。

    1K20

    七、构造函数与析构函数

    在对象赋值、函数参数传递、函数返回值等情况下,如果涉及同类型对象的复制,可能会隐式调用拷贝构造函数。...形式:ClassName(ClassName&& other); 特点: 移动构造函数的参数是同类型对象的右值引用。 通过移动构造函数,可以避免不必要的资源复制,提高程序性能。...default; // 显式要求编译器生成默认拷贝构造函数 // ... }; delete delete关键字用于删除某些特殊的成员函数或者重载的函数,这意味着这些函数不能被调用,无论是显式调用还是隐式调用...,表示该构造函数是显式的,这意味着它不能用于隐式类型转换。.... */ } // 显式构造函数 // ... }; void func() { MyClass obj = 10; // 错误:构造函数是显式的,不能用于隐式类型转换 MyClass

    13810

    第5章 | 对值的引用,使用引用,引用安全

    Matthew $ 但是,如果你已经阅读过第 4 章关于“移动”的部分,就会对 show 这个函数的定义产生一些疑问。...表达式 &e 会产生对 e 值的共享引用,如果 e 的类型为 T,那么 &e 的类型就是 &T,读作“ref T”。共享引用是 Copy 类型。 可变引用允许你读取和修改值。...最重要的是,它们都只是机器级别的地址。但在实践中,Rust 的引用会给人截然不同的感觉。 在 C++ 中,引用是通过类型转换隐式创建的,并且是隐式解引用的: // C++代码!...// 把20存入x,r本身仍然指向x 在 Rust 中,引用是通过 & 运算符显式创建的,同时要用 * 运算符显式解引用: // 从这里开始回到Rust代码 let x = 10; let r = &...(*s, 0); // 错误:指向了已被丢弃的数组的元素 从 smallest 的签名可以看出它的参数和返回值必须具有相同的生命周期 'a。

    10610

    由 Go 结构体指针引发的值传递的思考

    S } 要回答这个问题,涉及到 Go 中的几个概念,隐式引用转换和可寻址 Addressable 隐式引用转换 先看第一次调用 Write 的地方,首先 sVals[1] 返回的是一个 S 类型的值赋值给变量...s := sVals[1] s.Write() 那么为什么第二个 Write 调用无法编译通过呢?...map 的值传递 在 Go 中,所有的函数参数和返回值都是通过值传递的,这意味着它们都是原始数据的副本,而不是引用或指针。...所以上述代码中 sVals[1] 返回的是一个副本,也就是说这是一个临时值,而对于临时值是不可寻址的。所以引用转换是不可能的,最后无法编译通过报出错误。...为什么要这样设计 为什么 map 要返回一个副本回来,而不是返回原始对象的地址?这种设计选择是出于安全性和一致性的考虑。

    23910

    Chapter 2: auto

    1.更多的使用auto而不是显式类型声明 将大段声明缩减成auto 例如: typename std::iterator_traits::value_type currValue = *b;...2.当auto推导出错误类型时使用显式类型初始化方式 当表达式返回的类型是代理类的类型时,不能使用auto 例1: //提取出Widget对象的特征,并以vector的形式返回 //每一个...因为std::vector虽然持有bool,但是operator[]作用于vector时,并不会返回vector容器中元素的引用([]操作返回容器内元素的引用对于其他类型都适用,...为什么会存在这种类型的对象呢?因为vector是通过紧凑的形式来表示bool值,每一个bit代表一个bool。...,同时增强程序可移植性和减少重构复杂性;但也由于与隐式代理类的冲突,造成了一些潜在问题,但是这些问题不是auto引起的,而是代理类本身的问题,因此显式静态类型转换可以保留auto的优点,同时保证程序的正确性

    1.1K70

    【C++】你想要的——印刷模板儿

    较小的类型转化成较大的类型。 当然不会:隐式类型转化只有在 赋值:b=3;(产生临时变量);函数传参的时候(产生临时变量),才会发生隐式类型转化。...当b传值时,中间的临时变量具有常性(只读),而形参是可读可写,权限就会放大,也是不可以通过的,除非加了const,但是加了const就无法交换了,所以这样还是行不通的!...但是模板参数不同,他们就是不同类型 return 0; } 可能有人会问:s1=s2;  会不会发生隐式类型转换呢?...当然不会,隐式类型转换只有在类型相近才会发生。...但在链接的时候,test.cpp中,却不能找到它的地址,这是为什么??这就是模板和其他的区别! 链接错误原因: .cpp中的定义,不是实例化模板,他只是一个模板,没有任何实例化成任何类型。

    41430

    c++11新特性,所有知识点都在这了!

    auto:让编译器在编译器就推导出变量的类型,可以通过=右边的类型推导出变量的类型。...左值引用:对左值进行引用的类型。 右值引用:对右值进行引用的类型。 移动语义:转移资源所有权,类似于转让或者资源窃取的意思,对于那块资源,转为自己所拥有,别人不再拥有也不会再使用。...返回值优化:当函数需要返回一个对象实例时候,就会创建一个临时对象并通过复制构造函数将目标对象复制到临时对象,这里有复制构造函数和析构函数会被多余的调用到,有代价,而通过返回值优化,C++标准允许省略调用这些复制构造函数...关键字可以避免开发者在重写基类函数时无意产生的错误。...explicit explicit专用于修饰构造函数,表示只能显式构造,不可以被隐式转换,根据代码看explicit的作用: 不用explicit: struct A { A(int value)

    20.8K24

    第 13 章 拷贝控制

    所以,隐式销毁一个分配动态内存的内置指针类型的成员,并不会 delete它所指向的对象,需要显式调用 delete来回收资源。...新标准中,可以用容器保存不可拷贝的类型,只要它们能被移动即可。 返回左值引用的函数,连同赋值、下标、解引用和前置递增/递减运算符,都返回左值。...可以通过标准库中的 move函数来显式地将一个左值转换为对应的右值引用类型。在对一个对象使用 move函数后,可以对这个移后源对象进行销毁或赋值操作,但不能再使用它!...与拷贝操作不同,移动操作永远不会隐式地定义为删除的函数。如果既没有显式地要求生成=default的移动操作,又不满足编译器合成移动操作的条件,编译器根本就不会合成它们。...而如果用=default显式要求编译器生成移动操作,且编译器不能移动所有成员,则编译器会将移动操作定义为删除的函数。

    1K50

    【C++】C++中的类型转化

    说起类型转化,我们在C语言之前的学习中可以了解到,类型转换可以分为两种情况:隐式类型转化;显示类型转化。但是为什么在c++中还要继续对类型转化做文章呢?我们一起来看: 1....:隐式类型 转换和显式类型转换。...隐式类型转化:编译器在编译阶段自动进行,能转就转,不能转就编译失败 2....显式类型转化:需要用户自己处理 举个例子: int main() { double i = 4.2; //隐式类型转化 int a = i; //显示的强制类型转换 int...为什么还是2呢? 原因是:在编译时,因为是const修饰(不会修改),所以就会把a的值放入寄存器中,通过*p来改变的是内存中的a的值,但是a在寄存器中的值没有改变,依旧是2,所以打印时就是2。

    1.1K10

    Rust 标记Trait,公共词汇Trait

    例如,克隆 Vec 不仅会复制此向量,还会复制它的每个 String 元素。这就是 Rust 不会自动克隆值,而是要求你进行显式方法调用的原因。...像 Rc 和 Arc 这样的引用计数指针类型属于例外,即克隆其中任何一个都只会增加引用计数并为你返回一个新指针 Copy 对于大多数类型,赋值时会移动值,而不是复制它们。...移动值可以更简单地跟踪它们所拥有的资源 例外情况:不拥有任何资源的简单类型可以是 Copy 类型,对这些简单类型赋值会创建源的副本,而不会移动值并使源回到未初始化状态 如果一个类型实现了 std::marker...如果复制的开销很高,那么就不适合进行隐式复制 Default 某些类型具有合理的默认值:向量或字符串默认为空、数值默认为 0、Option 默认为 None,等等。...Rust 不会为结构体类型隐式实现 Default,但是如果结构体的所有字段都实现了 Default,则可以使用 #[derive(Default)] 为此结构体自动实现 Default AsRef 与

    9410

    Google C++ 编程风格指南(三):类

    可拷贝类型和可移动类型 如果你的类型需要, 就让它们支持拷贝 / 移动. 否则, 就把隐式产生的拷贝和移动函数禁用....可移动类型允许对象在初始化时得到来自相同类型的临时对象的值, 或在赋值时被赋予相同类型的临时对象的值 (因此所有可拷贝对象也是可移动的). std::unique_ptr 就是一个可移动但不可复制的对象的例子...对于用户定义的类型, 移动操作一般是通过移动构造函数和移动赋值操作符实现的. 拷贝 / 移动构造函数在某些情况下会被编译器隐式调用. 例如, 通过传值的方式传递对象....优点: 可移动及可拷贝类型的对象可以通过传值的方式进行传递或者返回, 这使得 API 更简单, 更安全也更通用....拷贝 / 移动构造函数与赋值操作一般来说要比它们的各种替代方案, 比如 Clone(), CopyFrom() or Swap(), 更容易定义, 因为它们能通过编译器产生, 无论是隐式的还是通过 =

    83040
    领券