问题标签 [rvalue-reference]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - 只提供一个移动构造函数是不好的形式吗?
我想Foo
从函数返回一个不可复制的类型对象。这基本上是一个辅助对象,调用者将使用它来执行一组操作,并使用析构函数在操作完成后执行一些清理。
在rvalue references出现之前,我会返回 ashared_ptr<Foo>
或类似的东西。使用右值引用,另一种选择是将构造函数和复制构造函数设为私有,并且唯一的公共构造函数是移动构造函数。Foo
看起来像这样:
我的问题是这样做是否会是不好的形式,或者看起来是否合理。我想不出这会导致问题或难以阅读的任何原因,但是当涉及到右值引用时,我仍然是一个新手,所以可能有一些我没有想到的考虑因素。
rvalue-reference - 在隐式转换中移动构造函数(右值引用)
我正在将 C++ 项目从 MSVC 2008 升级到 2010,并且由于新的 CComBSTR 移动构造函数 [CComBSTR( CComBSTR&& )],由于调用不明确,我收到编译器错误。
本质上,我们有一个 String 类,它与具有 CComBSTR 的强制转换运算符的 std::wstring 非常相似。这类似于以下代码:
现在,在代码中的某些地方,我们执行以下操作:
在 VS2008 中,这会起作用,因为 CString 对象将被隐式转换为 CComBSTR 右值,并且将调用 CComBSTR 的复制构造函数(采用 const CComBSTR&)来构造 objectName。
然而,在带有 C++0x 的 VS2010 中,编译器给出了一个模棱两可的调用错误,因为 CComBSTR 右值似乎同时适合复制构造函数和移动构造函数。
虽然有点笨拙,但我对这个问题的解决方案是 static_cast 对 GetName 的调用:
这两行编译都没有错误,但我需要您就这是否非法、不好的做法或未定义提出建议。谢谢你。
c++ - 绑定对 object-or-dummy 的引用的样式
将右值引用绑定到给定对象或其临时副本的最佳方法是什么?
(这段代码在我最近的 GCC 4.6 上不起作用……我记得它以前可以工作,但现在它总是返回一个副本。)
在第一行,从左值转换为 x 值static_cast
。my_A
(C++0x §5.2.9/1-3)static_cast
第二行的内部执行左值到右值的转换,外部的从这个prvalue获得一个xvalue。
这似乎是受支持的,因为根据 §12.2/5,命名引用有条件地绑定到临时。相同的技巧在 C++03 中的工作方式与const
引用相同。
我也可以不那么冗长地写同样的东西:
现在它更短了。第一个缩写是有问题的:move
应该表示对象正在发生某些事情,而不仅仅是左值到x值到左值的洗牌。令人困惑的是,move
不能在 之后使用,:
因为函数调用会中断临时引用绑定。语法A(my_A)
可能比 更清晰static_cast
,但它在技术上等同于 C 风格的演员表。
我也可以一路走下去,完全用 C 风格的演员表来写:
毕竟,如果这要成为一个成语,它一定很方便,而且static_cast
无论如何也不能真正保护我免受任何伤害——真正的危险是无法直接绑定到my_A
此案中true
。
另一方面,这很容易被重复三遍的类型名所支配。如果A
被替换为一个又大又丑的模板 ID,我真的想要一个真正的捷径。
(请注意,V
尽管出现五次,但只评估一次:)
像宏一样骇人听闻,我认为这是最好的选择。这有点危险,因为它返回一个 xvalue,所以它不应该在引用初始化之外使用。
一定有什么我没有想到的……建议?
c++ - C++0x:条件运算符、xvalues 和 decltype
我在这里重新发布一个comp.std.c++ Usenet 讨论,因为该组变得非常不可靠。我在那儿提交的最后几篇文章已经无效,活动几乎停止了。我怀疑我被禁止和/或其他人只是失去了兴趣。希望所有感兴趣的人都能找到这个讨论,并且会有一个普遍的迁移。也许那时他们会任命一位新的主持人。
你好!
根据我目前对条件运算符和 xvalues 的 N3126 草案的解释,我希望以下断言成立:
5.16/4 说:
如果第二个和第三个操作数 [对条件运算符] 是相同值类别的左值并具有相同类型,则结果是该类型和值类别 [...]
虽然,它并没有清楚地说明生成的 glvalue 指的是 glvalue 操作数所指的对象之一——或者这是暗示的,否则它会返回一个纯右值?在 C++0x 模式下使用 GCC 4.5.1,第二个断言失败。引用 k 似乎是指一些临时对象。如果冒号周围的两个操作数都是相同类型的 xvalue,有人可以澄清是否允许编译器创建这样的临时变量?
我目前假设 GCC 是错误的和/或就 xvalues 而言不是最新的。
接下来的问题是:能够检测出表达式的值类别不是很好吗?如果我们忽略条件运算符,我们可以使用 decltype 检测表达式的值类别。但是什么是
应该屈服?使用 GCC 4.5.1,xvalue 变量被初始化为 false。这符合当前的标准草案吗?
TIA,塞巴斯蒂安
c++ - C++0x右值引用模板参数推导
鉴于GMan在这里炮制的美味邪恶的auto_cast
实用功能,我一直试图弄清楚为什么当我尝试从右值(在 MSVC 10.0 上)时它不能为我编译。auto_cast
这是我正在使用的代码:
尽我所能,我尝试遵循 C++0x 参考折叠规则和此处概述的模板参数推导规则,据我所知,上面给出的代码应该可以工作。
回想一下,在 0x 之前的 C++ 中,不允许对引用进行引用:像 A& & 这样的东西会导致编译错误。相比之下,C++0x 引入了以下引用折叠规则:
- A& & 变成 A&
- A& && 变成 A&
- A&& & 变成 A&
- A&& && 变成 A&&
第二条规则是一个特殊的模板参数推导规则,用于通过对模板参数的右值引用获取参数的函数模板:
在这里,以下规则适用:
- 当 foo 在 A 类型的左值上调用时,T 会解析为 A&,因此,根据上面的引用折叠规则,参数类型实际上变成了 A&。
- 当 foo 在类型 A 的右值上调用时,T 解析为 A,因此参数类型变为 A&&。
现在,当我将鼠标悬停在对 的调用上时auto_cast( 5.0f )
,工具提示正确地将其返回值显示为auto_cast_wrapper<float>
。这意味着编译器正确地遵循了规则 2:
当 foo 在 A 类型的右值上调用时,T 会解析为 A。
所以既然我们有一个auto_cast_wrapper<float>
,构造函数应该实例化一个float&&
。但是错误消息似乎暗示它实例化为float
按值获取。
这是完整的错误消息,再次显示 T=float 正确但 T&& 参数变为 T?
有什么想法吗?
c++ - 调用基类移动 ctor [C++0x]
哪个是调用基类移动ctor的正确方法?
这(在 MSVC2010 中有效,但在 CBuilder2010 中无效):
或(在 CBuilder2010 中有效,但在 MSVC2010 中无效):
或者,他们都错了吗?如果是这样,正确的方法是什么(根据 C++0x 标准中的规定)?
注意:我不知道如何让它在 CBuilderXE 中工作(两个版本都不起作用)。
c++ - 在 C++ 中将非常量引用传递给右值
在以下代码行中:
使用原型调用函数:
我收到此错误:
libcpfs/mkfs.cc:99:53:错误:从“File”类型的右值对“File&”类型的非常量引用无效初始化
libcpfs/mkfs.cc:30:13: 错误: 传递 'void bootrec_reset(File&, ssize_t)' 的参数 1
我知道您不能const &
根据标准将非常量引用 () 传递给右值。但是,MSVC 允许您执行此操作(请参阅此问题)。这个问题试图解释原因,但答案没有意义,因为他使用的是对文字的引用,这是一种极端情况,显然应该被禁止。
在给定的示例中,可以清楚地看到将发生以下事件顺序(就像在 MSVC 中一样):
File
的构造函数将被调用。File
对和的引用blksize
被压入堆栈。bootrec_reset
利用file
.- 从 中返回后
bootrec_reset
,临时File
对象被销毁。
有必要指出File
引用必须是非常量的,因为它是文件的临时句柄,在该文件上调用非常量方法。此外,我不想传递要在那里File
构造的构造函数参数bootrec_reset
,我也看不出有任何理由File
在调用者中手动构造和销毁对象。
所以我的问题是:
- 是什么证明 C++ 标准以这种方式不允许非常量引用?
- 如何强制 GCC 允许此代码?
- 即将到来的 C++0x 标准是否会改变这一点,还是新标准给我的东西在这里更合适,例如所有关于右值引用的胡言乱语?
c++ - 哪些类型的代码需要注意右值引用?
我看到很多人在理解右值引用时遇到问题。一旦新标准出台, “普通”C++ 代码(例如,使用标准库但未实现它)是否需要了解右值引用,或者人员/代码是否可以假装右值引用不存在?右值引用主要关注库实现者还是所有程序员?
c++ - D 是否有类似于 C++0x 的移动语义的东西?
std::vector<T>
具有外部资源(如or )的“值类型”的一个问题std::string
是复制它们往往非常昂贵,并且副本是在各种上下文中隐式创建的,因此这往往是性能问题。C++0x 对这个问题的回答是移动语义,它在概念上基于资源盗窃的思想,并在技术上由右值引用提供支持。
D 有什么类似于移动语义或右值引用的东西吗?