int&& d = 5
) используется крайне редко, чтобы продлить время жизни временному объекту.string&& Container::give()
), и означает: это ссылка на объект, который спокойно можно выпотрошить. Или в типах параметров — Container& Container::operator = (string&& x)
: то есть принимает объект, который больше не нужен.std::vector<int> doSmth() {
std::vector<int> r;
r.push_back(42);
return r;
}
...
std::vector<int> a = doSmth();
std::vector<int> r;
— создадим в стековом фрейме переменную r.return r;
— vector(const vector&) в какое-то место, предложенное вызывающей функцией.std::vector<int> a = doSmth();
— vector(const vector&) из этого места в a.return vector<int>{ 42 };
— то ни одного), но у нас-то Си++03. Не много конструкторов? А ведь зная, что объект больше не нужен, можем просто перенести указатель из одного вектора в другой, точка — даже впрямую, без оптимизаций, никаких перевыделений памяти. Вот этот прямой перенос указателей я и назвал словом «выпотрошить объект».container = string("alpha") + "bravo";
Тут в контейнер перемещается временная строка.string a = "alpha"; container = a;
Не компилируется: строка a не временная.container1 = container2.give();
Перенос строки из контейнера в контейнер без выделения памяти.string a = "alpha"; container = std::move(a);
Компилируется (мы функцией move сказали: с обычным объектом обращаться как с временным), но в результате в строке a может быть что угодно и не стоит закладываться на дальнейшее её значение. Но объект после потрошения в любом случае должен быть корректным, ведь ему ещё вызывать деструктор :)myString=std::move(x)
или std::swap(myString, x)
. А они, в свою очередь — внутренняя string::op= и дружественная swap — прямыми играми с указателями. TmstsLocalTrain = packed record
_mem0000 : array [$0000..$0061] of byte;
// 0062
HeadWagon : dword; // Головная единица ПС
// 0066
TailWagon : dword; // Хвостовая единица ПС
// 006A
LocWagon : dword; // Управляемая игроком единица ПС
// 006E
_mem006E : dword;
// 0072
Caps : dword;
// 0076
_mem0076 : array [$0076..$0091] of byte;
// 0092
Speed : single; // Скорость по скоростемеру, м/с
// 0096
Acceleration : single; // Ускорение, м/с2
// 009A
_mem009A : array [$009A..$00D5] of byte;
// 00D6
TimeSec : single;
// 00DA
ReversingOdometer : single;
// 00DE
end;
struct Arr1 {
int length;
int data[100];
}
struct Arr1 someFunc() {}
struct Arr2 {
int length;
int* data; // не забудь free(arr.data);
}
struct Arr2 someFunc() {}
int sprintf ( char * str, const char * format, ... );
class Committer { // interface
public:
virtual void commit() = 0;
virtual ~Committer() = default;
}
enum class ErrCode { OK, UNCLONEABLE, BAD_RECIPIENT };
struct CommitObj {
ErrCode errCode;
std::unique_ptr<Committer> action;
}
class UiObj {
public:
virtual CommitObj startClone(std::shared_ptr<UiObj> recipient) = 0;
}
template <class T> struct string_traits;
template <class C, class T, class A>
struct string_traits<std::basic_string<C,T,A>> {
using Ch = C;
using Tr = T;
using Sv = std::basic_string_view<C,T>;
};
template <class C, class T>
struct string_traits<std::basic_string_view<C,T>> {
using Ch = C;
using Tr = T;
using Sv = std::basic_string_view<C,T>;
};
template <class C>
struct string_traits<const C*> {
using Ch = C;
using Tr = std::char_traits<C>;
using Sv = std::basic_string_view<C>;
};
template <class C, size_t N>
struct string_traits<C[N]> {
using Ch = C;
using Sv = std::basic_string_view<C>;
};
template<class S>
using s_v_t = typename string_traits<std::remove_cvref_t<S>>::Sv;
namespace detail {
template <class Sv>
Sv remainderSv(Sv s, Sv prefix)
{
if (s.length() <= prefix.length()
|| !s.starts_with(prefix))
return {};
return s.substr(prefix.length(), s.length() - prefix.length());
}
}
/// @brief remainderSv
/// Same for prefix only
template <class A>
inline auto remainderSv(const A& s, s_v_t<A> prefix) -> s_v_t<A>
{ return detail::remainderSv<s_v_t<A>>(s, prefix); }
class BuildCircle extends BuildShape
.Implicitly-declared move constructor
If no user-defined move constructors are provided for a class type (struct, class, or union), and all of the following is true:
- there are no user-declared copy constructors;
- there are no user-declared copy assignment operators;
- there are no user-declared move assignment operators;
- there is no user-declared destructor.
then the compiler will declare a move constructor as a non-explicit inline public member of its class with the signature T::T(T&&).