SORU
26 Ocak 2014, Pazar


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
26 Ocak 2014, Pazar


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:

Taxonomy

(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.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Break

    Break

    10 Aralık 2005
  • Dive In

    Dive In

    17 Temmuz 2013
  • HSmasteryoda .

    HSmasteryoda

    22 Ocak 2010