Neden`:: std` `adlı hareket std::move`?
C 11 std::move(x)
işlevi gerçekten hiçbir şey hareket etmez. R-değeri için sadece bir döküm. Neden böyle bir uygulama yapıldı? Bu yanıltıcı değil mi?
CEVAP
std::move(x)
rvalue için dökme özellikle xvalue, as opposed to a prvalue için sadece doğrudur. Ve bir döküm move
adında olması bazen insanların kafasını karıştıran da doğrudur. Ancak bu adlandırma amacı şaşırtmak için değil, kodunuzu daha okunabilir hale getirmek için değil.
move
geçmişi the original move proposal in 2002 kadar uzanır. Bu kağıt ilk rvalue başvurusu tanıttı, ve sonra daha verimli std::swap
bir yazmak için nasıl gösterir:
template <class T>
void
swap(T& a, T& b)
{
T tmp(static_cast<T&&>(a));
a = static_cast<T&&>(b);
b = static_cast<T&&>(tmp);
}
Tarih, "&&
" muhtemelen oldu . tek şey bu noktada hatırlamak gerekiyor ^em>mantıksal ve. Kimse rvalue başvuruları ile tanıdık, ne de bir rvalue static_cast<T>(t)
yapmak bir kopyasını yapmak değil iken () bir lvalue döküm etkileri oldu. Bu kod okuyucular doğal olarak düşündü:
swap
işin nasıl yürüyeceğini biliyorum (geçici kopyala ve değerleri değiştirmek sonra), ama o çirkin atmalarını amacı nedir?!
swap
gerçekten sadece bir-durmak permütasyon-değiştirme algoritmaları her türlü için olduğunu unutmayın. Bu tartışmaçok, swap
çok daha büyük.
Teklifi sunarsözdizimi şekerdeğil kesin nakleden bir şey daha okunabilir static_cast<T&&>
değiştirirneama daha doğrusuneden:
template <class T>
void
swap(T& a, T& b)
{
T tmp(move(a));
a = move(b);
b = move(tmp);
}
I. e. move
static_cast<T&&>
ve şimdi kodu şu var atmalarını neden olarak oldukça müstehcen olduğu için şeker sadece kullanımı: semantik hareket etkinleştirmek için!
Tarihi bağlamında, bu noktada birkaç kişi gerçekten rvalues ve hareket semantiği kağıdı olarak açıklamaya çalışır rağmen) arasındaki yakın ilişki, anladığını anlamak gerekir:
Taşıma semantiği otomatik olarak rvalue verildiğinde oyuna gelecek argümanlar. Bu bir kaynak hareketli olduğundan son derece güvenlidir rvalue programın geri kalanı tarafından fark edilemez (kimsede yok bir fark tespit sırada rvalue başvurusu).
Zamanı geldiğinde swap
yerine bu gibi sunuldu:
template <class T>
void
swap(T& a, T& b)
{
T tmp(cast_to_rvalue(a));
a = cast_to_rvalue(b);
b = cast_to_rvalue(tmp);
}
O zaman insanlar da ona baktı ve dedi ki:"
Ama neden rvalue döküm misin?
Olduğu gibi move
, hiç kimse sormadı kullanarak:
Ama neden hareket ediyor?
Yıllar geçti ve teklifi rafine olarak, lvalue ve rvalue kavramları içine rafine edildideğer kategorileribugün:
(resim utanmadan dirkgently çalıntı)
Ve bu yüzden bugün, eğer swap
tam olarak söylemek istersekneyapıyor, yerinenedenbunu gerektiği gibi:
template <class T>
void
swap(T& a, T& b)
{
T tmp(set_value_category_to_xvalue(a));
a = set_value_category_to_xvalue(b);
b = set_value_category_to_xvalue(tmp);
}
Ve herkes kendine sorman gereken soru ise yukarıdaki kodu daha fazla veya daha az okunabilir olmasıdır:
template <class T>
void
swap(T& a, T& b)
{
T tmp(move(a));
a = move(b);
b = move(tmp);
}
Hatta orijinal:
template <class T>
void
swap(T& a, T& b)
{
T tmp(static_cast<T&&>(a));
a = static_cast<T&&>(b);
b = static_cast<T&&>(tmp);
}
Herhangi bir olay, kalfa C programcı move
, başlık altında başka bir şey dökme neler olduğunu bilmeli. Ve Acemi C programcısı, en az move
ile niyet etmek olduğunu bildirilirhareket ettirinaksine oluşturduğu,kopyalaeğer tam olarak anlamasalar bile, oluşturduğu,nasılbu gerçekleştirilir.
Eğer bir programcı bu işlevi başka bir isim altında isterse, ayrıca, std::move
Bu tekeli işleve sahip olmayan taşınabilir dil sihirli uygulama dahil yok. Eğer bir set_value_category_to_xvalue
kod ve yerine kullanmak istedim örneğin, önemsiz bunu yapmak için:
template <class T>
inline
constexpr
typename std::remove_reference<T>::type&&
set_value_category_to_xvalue(T&& t) noexcept
{
return static_cast<typename std::remove_reference<T>::type&&>(t);
}
C 14 daha anlaşılır olur:
template <class T>
inline
constexpr
auto&&
set_value_category_to_xvalue(T&& t) noexcept
{
return static_cast<std::remove_reference_t<T>&&>(t);
}
Eğer çok eğimlidir eğer iyi ise ancak ** 36 süslemek ve belki de yeni bir en iyi uygulama (C sürekli olarak gelişmekte olan sona erecek.
Neden viewWillAppear bir uygulama arka...
Neden güçlü adlı kullanabileceksiniz?...
Varsayılan neden atama move-kurucu/?...
Neden Çınlama ve VS2013 ayracı-başlatı...
Neden = listeler beklenmedik bir harek...