我有一个可复制构造的结构向量,但不可赋值:
struct Struct
{
inline Struct(const std::string& text, int n) : _text(text), _n(n) {}
inline Struct(const Struct& other) : _text(other._text), _n(other._n) {}
const std::string _text;
const int _n;
Struct& operator=(const Struct&) = delete;
};
Run Code Online (Sandbox Code Playgroud)
一切都很好.事实上,我甚std::vector<Struct>至可以将值作为函数的返回值传递.然而,这失败了:
std::vector<TextFragment> v1, v2;
v2 = v1;
Run Code Online (Sandbox Code Playgroud)
当然,错误是:
错误:C2280:'Struct&Struct :: operator =(const Struct&)':尝试引用已删除的函数
我不明白为什么它试图调用它.这是否是某种优化以避免重新分配向量的内存块?
为什么在这个例子中没有打印出来?我正在Coliru的Clang编译.
#include <iostream>
struct S
{
S() noexcept = default;
S(S&&) noexcept { std::cout << "move-ctor"; }
};
void f(S) {}
int main()
{
f(S{});
}
Run Code Online (Sandbox Code Playgroud) struct big_struct{
vector<int> a_vector;
map<string, int> a_map;
};
big_struct make_data(){
big_struct return_this;
// do stuff, build that data, etc
return return_this;
}
int main(){
auto data = make_data();
}
Run Code Online (Sandbox Code Playgroud)
我已经看到移动语义应用于构造函数,但在这段代码中,我想知道大结构是否在返回时完全复制.我甚至不确定它与移动语义有关.C++总是复制这种数据,还是优化?这段代码可以改变或改进吗?
返回矢量或地图的函数怎么样?这张地图/矢量被复制了吗?
#include <iostream>
using namespace std;
class Test
{
public:
Test()
{
printf("construct ..\n");
}
~Test()
{
printf("destruct...\n");
}
};
Test Get()
{
Test t = Test();
return t;
}
int main(int argc, char *argv[])
{
Test t = Get();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
控制台输出是:
$ g++ -g -Wall -O0 testdestructor.cc
$ ./a.out
Run Code Online (Sandbox Code Playgroud)
构造..
破坏...
std::unique_ptr<int> ptr() {
std::unique_ptr<int> p(new int(3));
return p; // Why doesn't this require explicit move using std::move?
} // Why didn't the data pointed to by 'p' is not destroyed here though p is not moved?
int main() {
std::unique_ptr<int> a = ptr(); // Why doesn't this require std::move?
std::cout << *a; // Prints 3.
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,函数ptr()返回一个副本p.如果p超出范围,数据"3"应被删除.但是代码如何在没有任何访问冲突的情况下工作?
我最近正在学习新的C++ 11功能.但是,我并不完全了解rvalues的一件事.
考虑以下代码:
string getText ()
{
return "Fabricati diem";
}
string newText = getText();
Run Code Online (Sandbox Code Playgroud)
调用以getText()创建复制到newText变量的r值.但这个右值究竟存储在哪里?复制后会发生什么?
根据我的理解,当创建临时对象时,将调用移动构造函数.这里getA()函数返回一个临时对象,但我的程序没有从移动构造函数中打印消息:
#include <iostream>
using namespace std;
class A
{
public:
A()
{
cout<<"Hi from default\n";
}
A(A && obj)
{
cout<<"Hi from move\n";
}
};
A getA()
{
A obj;
cout<<"from getA\n";
return obj;
}
int main()
{
A b(getA());
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我有一个非常基本的问题:返回std::vector<A>使用std::move是否是一个好主意?例如:
class A {};
std::vector<A> && func() {
std::vector<A> v;
/* fill v */
return std::move(v);
}
Run Code Online (Sandbox Code Playgroud)
我应该返回std::map,std::list..等等......这样?
假设我有以下代码.
std::string foo() {
std::string mystr("SOMELONGVALUE");
return mystr;
}
int main() {
std::string result = foo();
}
Run Code Online (Sandbox Code Playgroud)
当我调用'foo'时,数据是mystr复制还是移入result?我相信它是移动C++ 11风格,但我希望澄清和/或链接来显示.
谢谢!
编辑:我想在使用g ++编译c ++ 11或更高版本时,我想知道这个问题的答案.
在尝试编写一个类,调用它的构造函数和析构函数之间的持续时间时,我遇到了我认为是clang中的错误.(编辑:这不是一个bug;它是实现定义的副本省略)
timer下面的结构保存一个指向作为引用传入的持续时间对象的指针,并将范围的持续时间添加到此.
#include <iostream>
#include <chrono>
struct timer {
using clock = std::chrono::high_resolution_clock;
using time_point = clock::time_point;
using duration = clock::duration;
duration* d_;
time_point start_;
timer(duration &d) : d_(&d), start_(clock::now()) {}
~timer(){
auto duration = clock::now() - start_;
*d_ += duration;
std::cerr << "duration: " << duration.count() << std::endl;
}
};
timer::duration f(){
timer::duration d{};
timer _(d);
std::cerr << "some heavy calculation here" << std::endl;
return d;
}
int main(){
std::cout << "function: " << f().count() << std::endl;
} …Run Code Online (Sandbox Code Playgroud) c++ ×10
c++11 ×5
move ×3
clang++ ×1
copy-elision ×1
destructor ×1
return ×1
stdvector ×1
vector ×1