调用左值引用构造函数而不是右值引用构造函数

2024-04-25

有这样的代码:

#include <iostream>

class F {
public:
   F() = default;
   F(F&&) {
      std::cout << "F(F&&)" << std::endl;
   }
   F(F&) {
      std::cout << "F(F&)" << std::endl;
   }
};

class G {
   F f_;
public:
   G(F&& f) : f_(f) {
      std::cout << "G()" << std::endl;
   }
};

int main(){
   G g = F();
   return 0;
}

输出是:

F(F&)
G()

Why F(F&)调用构造函数而不是F(F&&)类的构造函数中的构造函数G?类的构造函数的参数G is F&& f这是右值引用,但调用了左值引用的构造函数。


为什么在类G的构造函数中调用F(F&)构造函数而不是F(F&&)构造函数?

Because f是一个左值。尽管它是bound到一个右值,其类型是对的右值引用F,它也是一个命名变量。这使它成为左值。别忘了对象的值类别并不由其类型决定,反之亦然。

当您将左值传递给函数时,只有左值引用可以绑定到它。如果您只想捕获右值,您应该按如下方式更改代码:

class G {
    F f_;
public:
    G(F&& f) : f_(std::move(f)) {
       std::cout << "G()" << std::endl;
    }
};

或者,您可以使用std::forward<>(),在本例中是等效的,但使您的意图转发 f更清楚:

class G {
    F f_;
public:
    G(F&& f) : f_(std::forward<F>(f)) {
       std::cout << "G()" << std::endl;
    }
};

现在,最后一个定义很容易扩展,以便类型的左值和右值F可以绑定到参数f:

class G {
    F f_;
public:
    template<typename F>
    G(F&& f) : f_(std::forward<F>(f)) {
       std::cout << "G()" << std::endl;
    }
};

例如,这允许构造一个实例G这边走:

F f;
G g(f); // Would not be possible with a constructor accepting only rvalues

最后一个版本有一个caveat不过:你的构造函数基本上也可以作为复制构造函数 https://web.archive.org/web/20141205121901/http://flamingdangerzone.com:80/cxx11/2012/06/05/is_related.html,因此您可能需要显式定义所有可能的复制构造函数以避免尴尬的情况:

class G {
    F f_;
public:
    template<typename F>
    G(F&& f) : f_(std::forward<F>(f)) {
       std::cout << "G()" << std::endl;
    }
    G(G const&) = default;
    G(G&); // Must be defaulted out-of-class because of the reference to non-const
};

G::G(G&) = default;

由于非模板函数优于函数模板的实例化,因此在构造函数时将选择复制构造函数G来自另一个的对象G目的。当然,这同样适用于move构造函数。这留作练习。

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

调用左值引用构造函数而不是右值引用构造函数 的相关文章

  • 使用 C#.net 中的私有存储库的身份验证读取 BitBucket API

    我已经尝试了几天让 BitBucket API 为我工作 但是当涉及到让它为具有身份验证的私有存储库工作时 将问题设置为私有 当它们设置为公开 无需身份验证 一切正常 代码示例如下 static void Main string args
  • 为什么在排序输入上插入到树中比随机输入更快?

    现在我一直听说从随机选择的数据构建二叉搜索树比有序数据更快 这仅仅是因为有序数据需要显式重新平衡以将树高度保持在最低限度 最近我实现了一个不可变的treap http en wikipedia org wiki Treap 一种特殊的二叉搜
  • 为什么模板类的静态成员不唯一

    看一下下面的代码 include
  • 从 unsigned char* 到 char* 的转换无效

    这是一个代码 1 int main int argc char argv 2 3 signed char S psc 4 unsigned char U pusc 5 char C pc 6 7 C S 8 C U 9 10 pc psc
  • C# 中输入按键

    我尝试了这段代码 private void textBox1 KeyPress object sender KeyPressEventArgs e if Convert ToInt32 e KeyChar 13 MessageBox Sho
  • C++ 中可以使用匿名类作为返回类型吗?

    有没有办法在 C 中使用匿名类作为返回类型 我用谷歌搜索这可能有效 struct Test fun 但是这段代码无法编译 错误信息是 新类型不能在返回类型中定义 其实代码没有任何意义 我只是想弄清楚匿名类是否可以用作C 中的返回类型 这是我
  • 在 T4 代码生成中,如何从引用的程序集中获取类型?

    由于 T4 在项目上下文之外运行 因此我无权访问当前程序集或其他程序集 如何注册对引用程序集的访问 然后从中获取类型 我猜您想访问项目中建筑物的程序集 我在下面的示例代码中所做的是将一个名为 TestLib 的项目添加到我的解决方案中 我将
  • C 中的双重否定:是否保证返回 0/1?

    Is x 标准保证返回0 1 请注意 我是not询问 C 其中定义了 bool 类型 是的 在 C99 中 请参阅 6 5 3 3 4 逻辑非运算符的结果 是0如果其操作数的值比较 不等于0 1如果其操作数的值比较等于 0 结果具有类型in
  • 无法在 Visual Studio 和 vcpkg 中构建 cmake 项目(致命错误 C1083)

    我今天安装了vcpkg 启用了与Visual Studio的集成 即 vcpkg集成安装 并开始安装库 我基本上安装了 cpprestsdk 并触发了 boost 库的安装 然后我在 Visual Studio CMake 中打开该项目 当
  • 如何检查给定调用站点的重载决策集

    如何检查重载解析集 我在多个调用站点中使用了 4 个相互竞争的函数 在一个调用站点中 我期望调用一个函数 但编译器会选择另一个函数 我不知道为什么 这不是微不足道的 为了了解发生了什么 我正在使用enable if disable if打开
  • WPF ComboBox 中具有本地化名称的枚举

    我有一个列出枚举的组合框 enum StatusEnum Open 1 Closed 2 InProgress 3
  • C# 中不区分大小写的替换不使用正则表达式?

    有没有一种方法可以在不使用 C 中的正则表达式的情况下对字符串进行不区分大小写的替换 像这样的东西 string x Hello x x Replace hello hello world 你可以尝试类似的东西 string str Hel
  • 代码块 - 使用大地址感知标志进行编译

    如何使用以下命令在 64 位系统上编译 32 位应用程序LARGE ADRESS AWARE使用代码块标记 我需要使用超过 2GB 的内存 应该是添加的情况 Wl large address aware到链接标志 我不使用 CodeBloc
  • VS C# 中的依赖地狱,找不到依赖项

    我创建了一个图表 C 库 我们称之为chartlibrary 它本身依赖于多个第三方 dll 文件 在另一个可执行项目中 我们称之为chartuser 我参考了chartlibrary项目 两个项目位于 Visual Studio 中的同一
  • 为什么 std::atomic 比 volatile bool 慢很多?

    多年来我一直使用 volatile bool 来控制线程执行 并且效果很好 in my class declaration volatile bool stop In the thread function while stop do th
  • 如何使用 MongoDB 实现 ASP.NET Core 3.1 Identity?

    是一个 API 用于简化后端和逻辑代码来管理用户 密码 个人资料数据 角色 声明 令牌 电子邮件确认等 对于 Visual Studio 来说 支撑脚手架 https learn microsoft com en us aspnet cor
  • 曲线/路径骨架二值图像处理

    我正在尝试开发一个可以处理图像骨架的路径 曲线的代码 我想要一个来自两点之间骨架的点向量 该代码在添加一些点后结束 我没有找到解决方案 include opencv2 highgui highgui hpp include opencv2
  • SQL Server CE 不兼容的数据库版本

    我有一个 SQL Server CE 4 0 数据库 sdf文件 当我尝试从我的应用程序 WPF 对数据库进行查询时 出现以下错误 数据库版本不兼容 如果这是兼容文件 请运行修复 其他情况请参考文档 数据库版本 4000000 请求的版本
  • 从最大到最小的3个整数

    我是 C 初学者 我使用 编程 使用 C 的原理与实践 第二版 问题如下 编写一个程序 提示用户输入三个整数值 然后以逗号分隔的数字顺序输出这些值 如果两个值相同 则应将它们排列在一起 include
  • C#“var”关键字在 VB.NET 中的等价物是什么?

    例如 我如何获得 VB NET静态类型局部变量是static赋值右侧的表达式的类型 像这样 Dim http msdn microsoft com en us library 7ee5a7s1 aspx我的变量 3 你还需要 选项推断 ht

随机推荐