- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
最近我从 cppreference.../vector/emplace_back 中阅读了一个示例:
struct President
{
std::string name;
std::string country;
int year;
President(std::string p_name, std::string p_country, int p_year)
: name(std::move(p_name)), country(std::move(p_country)), year(p_year)
{
std::cout << "I am being constructed.\n";
}
我的问题:这 std::move
真的需要吗?我的观点是这个 p_name
没有用在构造函数的主体中,所以,也许语言中有一些规则默认使用 move 语义?
将初始化列表中的 std::move 添加到每个重成员(如 std::string
、std::vector
)会非常烦人。想象一下数百个用 C++03 编写的 KLOC 项目——我们是否应该在任何地方添加这个 std::move
?
这个问题:move-constructor-and-initialization-list答案是:
As a golden rule, whenever you take something by rvalue reference, you need to use it inside std::move, and whenever you take something by universal reference (i.e. deduced templated type with &&), you need to use it inside std::forward
但我不确定:按值传递而不是通用引用?
[更新]
为了让我的问题更清楚。可以将构造函数参数视为 XValue - 我的意思是过期值吗?
在这个例子中我们不使用 std::move
:
std::string getName()
{
std::string local = "Hello SO!";
return local; // std::move(local) is not needed nor probably correct
}
那么,这里是否需要:
void President::setDefaultName()
{
std::string local = "SO";
name = local; // std::move OR not std::move?
}
对我来说,这个局部变量是过期变量 - 所以可以应用 move 语义......这类似于按值传递的参数......
最佳答案
My question: is this std::move really needed? My point is that compiler sees that this p_name is not used in the body of constructor, so, maybe, there is some rule to use move semantics for it by default?
一般来说,当你想把一个左值变成一个右值,那么是的,你需要一个std::move()
。另见 Do C++11 compilers turn local variables into rvalues when they can during code optimization?
void President::setDefaultName()
{
std::string local = "SO";
name = local; // std::move OR not std::move?
}
For me this local variable is expiring variable - so move semantics could be applied... And this similar to arguments passed by value....
在这里,我希望优化器消除多余的 local
ALTOGETHER;不幸的是,实际情况并非如此。当堆内存开始发挥作用时,编译器优化会变得很棘手,请参阅 BoostCon 2013 Keynote: Chandler Carruth: Optimizing the Emergent Structures of C++ .我从 Chandler 的演讲中得出的一个结论是,当涉及到堆分配的内存时,优化器往往会放弃。
请参阅下面的代码,了解一个令人失望的示例。在这个例子中我没有使用 std::string
因为这是一个高度优化的类,带有内联汇编代码,通常会产生违反直觉的生成代码。为了增加侮辱, std::string
粗略地说至少是 gcc 4.7.2 中的引用计数共享指针( copy-on-write optimization ,现在被 std::的 2011 标准禁止字符串
)。所以没有std::string
的示例代码:
#include <algorithm>
#include <cstdio>
int main() {
char literal[] = { "string literal" };
int len = sizeof literal;
char* buffer = new char[len];
std::copy(literal, literal+len, buffer);
std::printf("%s\n", buffer);
delete[] buffer;
}
显然,根据“as-if”规则,生成的代码可以优化为:
int main() {
std::printf("string literal\n");
}
我已经在启用链接时间优化 (LTO) 的 GCC 4.9.0 和 Clang 3.5 上进行了尝试,但没有一个可以将代码优化到这个级别。我查看了生成的汇编代码:它们都在堆上分配了内存并进行了复制。嗯,是的,这令人失望。
堆栈分配的内存不同:
#include <algorithm>
#include <cstdio>
int main() {
char literal[] = { "string literal" };
const int len = sizeof literal;
char buffer[len];
std::copy(literal, literal+len, buffer);
std::printf("%s\n", buffer);
}
我已经检查了汇编代码:在这里,编译器能够将代码基本上简化为 std::printf("string literal\n");
.
因此,我对示例代码中多余的 local
可以被消除的期望并非完全不受支持:正如我后面的堆栈分配数组示例所示,可以做到。
Imagine hundreds of KLOC project written in C++03 - shall we add everywhere this
std::move
?
[...]
But I am not sure: passing by value is rather not universal reference?
"Want speed? Measure." (作者 Howard Hinnant)
您很容易发现自己进行优化只是为了发现您的优化使代码变慢。 :( 我的建议与 Howard Hinnant 的建议相同:衡量。
std::string getName()
{
std::string local = "Hello SO!";
return local; // std::move(local) is not needed nor probably correct
}
是的,但是我们有针对这种特殊情况的规则:它被称为命名返回值优化 (NRVO)。
关于c++ - 对于按值传递的重成员,构造函数的初始化列表中真的需要 std::move 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23929800/
我是 Spring 新手,这就是我想要做的事情: 我正在使用一个基于 Maven 的库,它有自己的 Spring 上下文和 Autowiring 字段。 它的bean配置文件是src/test/res
我在我的测试脚本中有以下列表初始化: newSequenceCore=["ls", "ns", "*", "cm", "*", "ov", "ov", "ov", "ov", "kd"] (代表要在控
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: Class construction with initial values 当我查看 http://en.
我得到了成员变量“objectCount”的限定错误。编译器还返回“ISO C++ 禁止非常量静态成员的类内初始化”。这是主类: #include #include "Tree.h" using n
我有如下所示的a.h class A { public: void doSomething()=0; }; 然后我有如下所示的b.h #include "a.h" class b: publi
我需要解析 Firebase DataSnapshot (一个 JSON 对象)转换成一个数据类,其属性包括 enum 和 list。所以我更喜欢通过传递 DataSnapshot 来手动解析它进入二
我使用 JQuery 一段时间了,我总是使用以下代码来初始化我的 javascript: $(document).ready( function() { // Initalisation logic
这里是 Objective-C 菜鸟。 为什么会这样: NSString *myString = [NSString alloc]; [myString initWithFormat:@"%f", s
我无法让核心数据支持的 NSArrayController 在我的代码中正常工作。下面是我的代码: pageArrayController = [[NSArrayController alloc] i
我对这一切都很陌生,并且无法将其安装到我的后端代码中。它去哪里?在我的页脚下面有我所有的 JS? 比如,这是什么意思: Popup initialization code should be exec
这可能是一个简单的问题,但是嘿,我是初学者。 所以我创建了一个程序来计算一些东西,它目前正在控制台中运行。我决定向其中添加一个用户界面,因此我使用 NetBeans IDE 中的内置功能创建了一个 J
我有 2 个 Controller ,TEST1Controller 和 TEST2Controller 在TEST2Controller中,我有一个initialize()函数设置属性值。 如果我尝
据我所知, dependentObservable 在声明时会进行计算。但如果某些值尚不存在怎么办? 例如: var viewModel ={}; var dependentObservable1 =
我正在阅读 POODR 这本书,它使用旧语法进行默认值初始化。我想用新语法实现相同的功能。 class Gear attr_reader :chainring, :cog, :wheel de
我按照 polymer 教程的说明进行操作: https://www.polymer-project.org/3.0/start/install-3-0 (我跳过了可选部分) 但是,在我执行命令“po
很抱歉问到一个非常新手的Kotlin问题,但是我正在努力理解与构造函数和初始化有关的一些东西。 我有这个类和构造函数: class TestCaseBuilder constructor(
假设我们有一个包含 30 列和 30 行的网格。 生命游戏规则简而言之: 一个小区有八个相邻小区 当一个细胞拥有三个存活的相邻细胞时,该细胞就会存活 如果一个细胞恰好有两个或三个活的相邻细胞,那么它就
我是 MQTT 和 Android 开放附件“AOA” 的新手。在阅读教程时,我意识到,在尝试写入 ByteArrayOutputStream 类型的变量之前,应该写入 0 或 0x00首先到该变量。
我有 2 个 Controller ,TEST1Controller 和 TEST2Controller 在TEST2Controller中,我有一个initialize()函数设置属性值。 如果我尝
我有一个inotify /内核问题。我正在使用“inotify” Python项目进行观察,但是,我的问题仍然是固有的关于inotify内核实现的核心。 Python inotify项目处理递归ino
我是一名优秀的程序员,十分优秀!