给出以下代码:
#include <iostream>
#include <vector>
#include <type_traits>
class Test {
public:
~Test() = default;
std::vector<int> m_vector;
};
int main() {
std::cout << std::is_nothrow_move_constructible_v<Test> << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它输出0,这意味着该类Test不能“不移动”。但是,如果我删除其中一个~Test()或m_vector那么它会返回1.
请问这个怎么解释?
作为参考,我将 clang++-7 与 C++17 一起使用。
我正在编写与 C API 通信的 Rust 代码,并且我需要某个结构来拥有固定的内存地址。到目前为止,我发现:
Pin用于指针;pin_mut用于固定堆栈的宏;PhantomPinned,我不清楚。如果我理解正确,PhantomPinned这将是最容易使用的:只需将其作为成员即可使我的结构自动具有固定的内存地址。它是否正确?
https://godbolt.org/z/E3ETx8a88
这是换UB吗?我有变异什么吗?UBSAN 没有报告任何内容。
#include <utility>
struct MyInt
{
MyInt(int ii): i(ii) {}
const int i;
MyInt& operator=(MyInt&& rh)
{
std::swap(const_cast<int&>(i), const_cast<int&>(rh.i));
return *this;
}
};
int main() {
MyInt i0(0);
MyInt i2(2);
i0 = std::move(i2);
return i0.i;
}
Run Code Online (Sandbox Code Playgroud) 我有以下代码:
\nstd::unique_ptr<T> first = Get();\n\xe2\x80\xa6\nT* ptr_to_class_member = GetPtr(obj);\n*ptr_to_class_member = std::move(*first.release());\nRun Code Online (Sandbox Code Playgroud)\n这是否会按预期运行,没有副本、1 次移动并且没有内存泄漏?
\n我有一个计时器的精简示例,我希望可以使用任何类型的可调用来实例化它。为了提高效率,是否建议预防性地将可调用对象移至数据成员中?
#include <concepts>
#include <cstdio>
#include <string>
#include <utility>
template <std::invocable Cb>
class timer {
public:
timer(Cb cb)
: cb_ { std::move(cb) }
{
}
auto call()
{
cb_();
}
private:
Cb cb_;
};
int main()
{
std::string something_to_print = "Hello World!\n";
timer some_timer([&]() { printf(something_to_print.c_str()); });
some_timer.call();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果移动或复制 lambda,我看不到程序集有任何差异。它有什么区别吗?
这是关于嵌入式 C++ 的。假设我有一个 struct Timer_t。
创建一个新对象
makeTimer()我们不能在设备上使用异常,并且要初始化计时器,我们可能会收到错误。
这就是为什么
std::expected<Timer_t,Error_t>由于我们使用 C++,人们往往会失败(太频繁地叫我来这里)
构造函数在这里只能使用一半,工厂函数对我们来说就是这样。
对于析构函数来说它工作得很好。如果我们离开了这个范围,我们就会取消它的初始化。事情应该是这样的。
现在问题开始了:如果我们返回makeTimer()对象,我们就可以移动。
更准确地说,我们称之为move constructor!
因此我们有 2 个对象,我们将对象称为析构函数。
更准确地说:
makeTimer() -> Timer_t() -> std::move/Timer_t(Timer_t &&) -> ~Timer_t() -> program ends -> ~Timer_t();
Run Code Online (Sandbox Code Playgroud)
对于移动来说,这是预期的行为。因此,它符合标准,但很烦人。
在嵌入式环境中,我发现人们在扩展代码时会面临很大的失败风险。
我只想在最后调用一次析构函数。
Error_t makeTimer(Timer_t & uninitialized Type)(会扼杀 std::expected 背后的想法并使代码不那么“好”)std::shared_ptr(额外费用...)或简单的布尔值。有没有更好的更清洁的想法来解决这个问题?我不可能是唯一一个拥有它的人。
当人们通常讨论或使用移动语义时,通常是在移动两个相同类型的类的上下文中.
例如:
MyObject(MyObject &&obj) { // Implementation }
Run Code Online (Sandbox Code Playgroud)
但是,如果MyObject在很大程度上只是像矢量一样包装STL容器,那该怎么办呢?是否会采用移动构造函数来获取向量并将其视为滥用功能?
MyObject(vector<backingtype> &&v) : i_Backing(move(v)) {}
Run Code Online (Sandbox Code Playgroud)
我问这个是因为我正在制作一个UTF-8感知的json解析器,它大量使用复制,而移动容器则足够快.
auto arrayParseRes = jsonArrayParse(input); // Array parse res
auto jsonArray = JsonArray(arrayParseRes.Parse_Value()); // Currently copying json values
Run Code Online (Sandbox Code Playgroud) C++ 98声明std :: vector元素应该有copy-constructors.在C++ 11中,情况已不再如此.相反,元素必须具有移动构造函数.
根据你对std :: vector的处理方式,你可能真的需要或者可能不需要调用copy-或move-构造函数,但标准中始终只需要其中一个.为什么?
更新:显然,前提是不正确的.我的困惑从阅读的答案,如朵朵此.
对于某些类来说S,重载一元operator +(或者可能operator *是非指针式类)如下所示是不好的做法?
struct S { S && operator + () & noexcept { return std::move(*this); } };
Run Code Online (Sandbox Code Playgroud)
它的目标是发明速记std::move.
S a;
S b = +a;
// instead of
S c = std::move(a);
Run Code Online (Sandbox Code Playgroud)
假设我有一个包含大量不同类的项目,它集中使用了移动语义.所有类都不模仿任何算术对应物.
c++ operator-overloading rvalue-reference move-semantics perfect-forwarding
是否有可能在C++中创建一次性变量而没有任何带有括号的时髦业务?
这是我想要实现的一个例子:
const float _phiTemp = atan2(tan(cluster.beta), tan(cluster.alpha));
const float phi = HALF_PI - std::abs(HALF_PI - std::abs(_phiTemp));
// After running this code I want _phiTemp to be unaccessible, and the
// compiler to send an error if I ever try
Run Code Online (Sandbox Code Playgroud)
这是我想要的漫长而丑陋的实现:
const float phi = 0;
{
const float _phiTemp = atan2(tan(cluster.beta), tan(cluster.alpha));
float& phiRef = const_cast<float&> phi;
phiRef = HALF_PI - std::abs(HALF_PI - std::abs(std::move(_phiTemp)));
}
// _phiTemp is disposed and phi is a const, and safely used in the …Run Code Online (Sandbox Code Playgroud) move-semantics ×10
c++ ×9
c++17 ×2
c++11 ×1
destructor ×1
embedded ×1
lambda ×1
lifetime ×1
memory ×1
rust ×1
scope ×1
std-expected ×1
stl ×1
type-traits ×1
vector ×1