我有一个 QWidget 衍生物,让我们假设标准 QWidget 示例
class MainWindow : public QMainWindow { //.. }
Run Code Online (Sandbox Code Playgroud)
对于此类 MainWindow 来说,满足五规则是否有意义,我的意思是特别是 Move 构造函数和移动赋值?
(因为主窗口应该只创建一次)
我正在尝试用 Rust 实现一个简单的 REPL 计算器,但我到处碰壁。
我在迭代硬编码字符串时消耗字符。当我点击数字字符时,我想将控制权传递给一个函数,该函数将消耗该数字的其余部分(假设该数字有多于一位数字)并返回该数字,并将其转换为整数。
Chars我在将迭代器传递给函数时遇到问题。我收到的错误是use of moved value: 'iter'.
我知道我不能改变我给别人的东西 - 其所有权已移动的东西 - 但我不知道有任何其他方法可以做到这一点,特别是因为 Chars 迭代器是不可复制的。
#[derive(Clone, Debug)]
enum Token {
Addition,
Substraction,
Multiplication,
Division,
Integer(i32),
Error,
}
fn consume_number(mut iter: std::str::Chars) -> Option<i32> {
while let Some(item) = iter.next() {
println!("{:?}", item);
}
return Some(1337);
}
fn tokenize(line: &str) -> Vec<Token> {
let mut iter = line.chars();
let mut tokens = Vec::new();
let mut token;
while let Some(c) = iter.next() {
if c.is_whitespace() { …Run Code Online (Sandbox Code Playgroud) 如何利用结构化绑定和元组来返回函数本地对象?
在函数中,我正在创建相互引用的本地对象,并且我希望在元组中返回这些对象,并在调用函数时使用结构化绑定来识别它们。我目前有这个:
std::tuple<Owner&&, State<Controller>&&, State<Ancillary>&&, State<Compressor>&&>
inline makeOwner() {
State<Controller>&& controller = State<Controller>();
State<Ancillary>&& ancillary = State<Ancillary>();
State<Compressor>&& compressor = State<Compressor>();
Owner&& owner = Owner(controller, ancillary, compressor);
return {owner, controller, ancillary, compressor};
}
// using the function later
const &&[owner, controller, ancillary, compressor] = makeOwner();
Run Code Online (Sandbox Code Playgroud)
这不起作用,并且我收到一条错误消息,指出返回值无法转换为上述返回类型的元组。我不确定为什么会出现这种情况,因为类型与声明相匹配。
最终,我试图创建一个方便的函数,这样我就不必每次想要创建新的所有者时都在函数中键入四行。这是我尝试使用结构化绑定来使这变得更容易。
编辑:我应该注意,我希望最后一行中的绑定引用所有者内部的对象。所以,副本是不够的。
我有一个需要 2 个参数的函数,但其中一个(地图容器)被传递给另一个函数:
void myFunc(const std::map<std::string, int> &myMap, int num) {
int x = internalFunc(myMap);
// do some stuff...
}
int internalFunc(const std::map<std::string, int> &myMap) {
// return some map statistics
}
Run Code Online (Sandbox Code Playgroud)
main.cpp 中的某处:
std::map<std::string, int> map1{ {"Hello", 10}, {"Hello2", 20}, {"Hello3", 30} };
myFunc(map1, 20);
Run Code Online (Sandbox Code Playgroud)
我的问题是:
移动语义是优化这段代码(使用移动将一个参数传递给另一个函数)的好方法,如下所示:
int internalFunc(std::map<std::string, int> &&myMap) {
// now gets rvalue reference
// return some map statistics
}
void myFunc(std::map<std::string, int> myMap, int num) {
int x = internalFunc(std::move(myMap));
// do some stuff...
} …Run Code Online (Sandbox Code Playgroud) cppreference.com和cplusplus.com说它是在<utility>. 但我的 IDE 将我发送到“C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\type_traits”。无法理解为什么。
以下是我正在尝试的玩具代码...我理解第一个和第二个。第一个将所有权授予_p. 第二个复制p到_p. 但第三个我没看懂……
std::move的是什么const shared_ptr &意思?谢谢。
class P { };
class A {
public:
// first one
A(std::shared_ptr<P> &p, int) : _p(std::move(p))
{
std::cout << "1st Ctor: "
<< p.use_count() << ", " << _p.use_count() << std::endl;
}
// second one
A(const std::shared_ptr<P> &p, std::string) : _p(p)
{
std::cout << "2nd Ctor: "
<< p.use_count() << ", " << _p.use_count() << std::endl;
}
// third one
A(const std::shared_ptr<P> &p) : _p(std::move(p)) …Run Code Online (Sandbox Code Playgroud) 请看下面的代码片段,在这种情况下 std::move() 的效率似乎很低。
class A {};
struct B {
double pi{ 3.14 };
int i{ 100 };
A* pa{ nullptr };
};
int main() {
B b;
std::vector<B> vec;
vec.emplace_back(b); // 1) without move
vec.emplace_back(std::move(b)); // 2) with move
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我在 Visual Studio 2019 [C++ 14,发布] 中得到以下反汇编:
vec.emplace_back(b); // 1) without move
00E511D1 push eax
00E511D2 push 0
00E511D4 lea ecx,[vec]
00E511D7 call std::vector<B,std::allocator<B> >::_Emplace_reallocate<B> (0E512C0h)
vec.emplace_back(std::move(b)); // 2) with move
00E511DC mov eax,dword ptr [ebp-18h]
00E511DF cmp …Run Code Online (Sandbox Code Playgroud) 如果我想为 std::vector 成员(或可移动对象)定义一个类似于 setter 的方法,我可以这样做:
void set(const std::vector<int>& v) { _v = v; }
Run Code Online (Sandbox Code Playgroud)
但我还需要添加
void set(std::vector<int>&& v) { _v = std::move(v); }
Run Code Online (Sandbox Code Playgroud)
正确的?为了处理可以移动的临时对象,最好同时定义两者吗?那么所有二传手都会加倍吗?谢谢。
我正在使用glutin,所以我的程序的主循环有一个移动关闭,我正在尝试使用rodio板条箱播放音频文件。使用以下代码,一切正常,每次程序循环时我都会发出一声哔哔声:
...
let sink: rodio::Sink = ...;
event_loop.run(move |event, _, control_flow | {
let sound_file = File::open("beep.ogg").unwrap();
let buf_wrap = BufReader::new(sound_file);
let source = rodio::Decoder::new(buf_wrap).unwrap();
sink.append(source);
...
});
...
Run Code Online (Sandbox Code Playgroud)
但是,这非常慢,因为我每次循环时都打开同一个文件,所以我尝试使用以下方法修复它:
...
let sound_file = File::open("beep.ogg").unwrap();
event_loop.run(move |event, _, control_flow | {
let buf_wrap = BufReader::new(sound_file);
...
});
...
Run Code Online (Sandbox Code Playgroud)
但是现在编译器给了我以下错误信息:
error[E0507]: cannot move out of `sound_file`, a captured variable in an `FnMut` closure
--> src/lib.rs:86:33
|
83 | let sound_file = File::open("beep.ogg").unwrap();
| ---------- captured outer variable …Run Code Online (Sandbox Code Playgroud) 最近,我发现自己经常遇到这样的情况:只有一个函数将某个对象作为参数。该函数必须复制该对象。
然而,该函数的参数也可能经常是临时的,因此我还想提供该函数的重载,该重载采用右值引用而不是常量引用。
两种重载的区别仅在于它们具有不同类型的引用作为参数类型。除此之外,它们在功能上是等效的。
例如,考虑这个玩具示例:
void foo(const MyObject &obj) {
globalVec.push_back(obj); // Makes copy
}
void foo(MyObject &&obj) {
globalVec.push_back(std::move(obj)); // Moves
}
Run Code Online (Sandbox Code Playgroud)
现在我想知道是否有一种方法可以通过例如根据另一个函数实现一个函数来避免这种代码重复。
例如,我正在考虑根据 move-one 实现复制版本,如下所示:
void foo(const MyObject &obj) {
MyObj copy = obj;
foo(std::move(copy));
}
void foo(MyObject &&obj) {
globalVec.push_back(std::move(obj)); // Moves
}
Run Code Online (Sandbox Code Playgroud)
然而,这似乎仍然不理想,因为现在调用 const ref 重载时会发生复制和移动操作,而不是之前所需的单个复制操作。
此外,如果对象不提供移动构造函数,那么这将有效地将对象复制两次(据我所知),这违背了首先提供这些重载的整个目的(尽可能避免复制)。
我确信人们可以使用宏和预处理器将某些东西组合在一起,但我非常希望避免在其中涉及预处理器(出于可读性目的)。
因此,我的问题是:是否有可能实现我想要的目标(有效地仅实现一次功能,然后根据第一个重载实现第二个重载)?
如果可能的话,我想避免使用模板。
c++ rvalue-reference move-semantics perfect-forwarding c++11