Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
При написании программ, я стараюсь использовать возможности C++xx по минимуму, для улучшения читаемости кода
Widget&& var1 = someWidget;
Widget var1 = someWidget;
Widget&& var1 = someWidget1+someWidget2;
Widget _var1 = someWidget1+someWidget2;
Widget* var1=&_var1?
Widget&& var1 = static_cast<Widget&&>(someWidget);
Widget var2,var3;
var2=var1;
var3=var1;
Widget _var1 = someWidget1+someWidget2; //Будет вызван move-конструктор(если он есть)
Widget&& var1 = someWidget1+someWidget2; //На стеке будет создан объект, посредством move ctor(если он есть), после чего на этот объект будет создана ссылка.
Widget&& var1 = static_cast<Widget&&>(someWidget);//создаём объект на стеке, воруя содержимое someWidget. someWidget нельзя использовать более
Widget var2,var3;//default ctor
var2=var1;//operator=(const Widget& rhs)
var3=var1;//operator=(const Widget& rhs)
var2=std::move(var1);//operator=(Widget&& rhs)
var3=var1;//Уупс
И еще — внутри функции foo(T &&x) переменная x является lvalue, т.е. можно смело писать a=x; b=x;?
Похоже, что && является признаком «разрушать можно»…
Есть ли хоть один пример, когда действительно имеет смысл писать
#include <iostream>
class A{
public:
virtual void foo()
{
std::cout << "A\n";
}
};
class B: public A
{
public:
void foo() override
{
std::cout << "B\n";
}
};
int main()
{
A a = B();//bad slicing
A&& b = B();
a.foo();
b.foo();
};
A&& x=f ? A() : B();
x.foo();
A&& boo(){ return B(); }
···
A&& x=boo();
x.foo();
template<class _Ty> inline
typename remove_reference<_Ty>::type&&
move(_Ty&& _Arg) _NOEXCEPT
{ // forward _Arg as movable
return ((typename remove_reference<_Ty>::type&&)_Arg);
}
struct A {
B b;
void setB(const B& obj)
{
b = obj;
}
void setB(B&& obj)
{
b = std::move(obj);
}
};
B makeB()
{
return B();
}
void func()
{
A a;
auto&& b = makeB();
a.setB(b);
}
class A
{
public:
A(A&& a) = default;
void operator=(A&& a) = default;
private:
std::vector<int> myVec;
};
class A
{
public:
A(const std::string& name_) : name(name_) {}
private:
std::string name;
};
class A
{
public:
A(std::string&& name_) : name(std::move(name_)) {}
private:
std::string name;
};
std::string name = "my_name";
A a(name);
class A
{
public:
template<typename T>
A(T&& name_) : name(std::forward(name_)) {}
private:
std::string name;
};
Проблема тут в том, что даже если все члены класса поддерживают move-семантику, такие методы не генерируются компилятором автоматически
#include <iostream>
#define F {std::cout << __PRETTY_FUNCTION__ << std::endl;}
struct B
{
B() F
~B() F
B(const B&) F
B(B&&) F
B& operator=(const B&) F
B& operator=(B&&) F
};
struct A
{
B b;
};
int main()
{
A a1;
A a2(a1);
A a3(std::move(a2));
return 0;
}
B::B()
B::B(const B&)
B::B(const B&)
B::~B()
B::~B()
B::~B()
struct A
{
A()=default;
A(A&&)=default;
B b;
};
B::B()
B::B(const B&)
B::B(B&&)
B::~B()
B::~B()
B::~B()
B::B()
B::B(const B&)
B::B(const B&)
B::~B()
B::~B()
B::~B()
B::B()
B::B(const B&)
B::B(B&&)
B::~B()
B::~B()
B::~B()
B::B()
B::B(const B&)
B::B(B&&)
B::~B()
B::~B()
B::~B()
__thiscall B::B(void)
__thiscall B::B(const struct B &)
__thiscall B::B(const struct B &)
__thiscall B::~B(void)
__thiscall B::~B(void)
__thiscall B::~B(void)
class A
{
public:
A(std::string name_) : name(std::move(name_)) {}
private:
std::string name;
};
«Универсальные» ссылки в C++11 или T&& не всегда означает «Rvalue Reference»