Taşınan bir nesne ile ne yapabilirim?


138

Standart, bir nesne taşındıktan sonra ne yapabileceğimi kesin olarak tanımlıyor mu? Taşınan bir nesne ile yapabileceğiniz tek şeyin onu yıkmak olduğunu düşünürdüm, ama bu yeterli olmazdı.

Örneğin, işlev şablonunu swapstandart kitaplıkta tanımlandığı gibi alın:

template <typename T>
void swap(T& a, T& b)
{
    T c = std::move(a); // line 1
    a = std::move(b);   // line 2: assignment to moved-from object!
    b = std::move(c);   // line 3: assignment to moved-from object!
}

Açıkçası, taşınan nesnelere atamak mümkün olmalıdır, aksi takdirde 2 ve 3 satırları başarısız olur. Peki taşınan nesnelerle başka ne yapabilirim? Bu ayrıntıları standartta tam olarak nerede bulabilirim?

(Bu arada, neden 1. satır T c = std::move(a);yerine T c(std::move(a));?)

Yanıtlar:


53

Taşınan nesneler belirtilmemiş, ancak geçerli bir durumda var. Bu, nesne artık çok fazla şey yapamayabileceğini düşündürse de, tüm üye işlevlerinin yine de tanımlanmış davranışlar - dahil olmak üzere operator=- ve tüm üyeleri belirli bir durumda - göstermesi gerektiğini ve yine de imha gerektirdiğini göstermektedir. Standart, her UDT'ye özgü olacağı için belirli bir tanım vermez, ancak Standart türler için spesifikasyonlar bulabilirsiniz. Bazı kaplar nispeten açıktır - sadece içeriklerini taşırlar ve boş bir kap iyi tanımlanmış geçerli bir durumdur. Temel öğeler taşınan nesneyi değiştirmez.

Yan not: Bence bu T c = std::move(a), hareket yapıcısı (veya hiçbir hareket sağlanmamışsa kopya yapıcısı) açıksa fonksiyonun başarısız olacağına inanır .


26
Değil tüm üye işlevleri davranışını tarif sergileyecektir. Sadece ön koşulu olmayanlar. Örneğin pop_back, taşınmak istemezsiniz vector. Ama kesinlikle olup olmadığını öğrenebilirsiniz empty().
Howard Hinnant

6
@Howard Hinnant: pop_backboş bir vectorbellekten tanımlanmamış davranış zaten var, bu yüzden pop_backtanımsız davranış sergileyen taşınmış bir vektörden tutarlı olduğundan eminim .
Köpek yavrusu

12
Taşınan nesneleri tartışıyoruz. Boş durumda olduğu bilinen nesneler değil. Taşınan nesneler belirtilmemiş bir duruma sahiptir (elbette aksi belirtilmedikçe). [lib.types.movedfrom]
Howard Hinnant

5
@ Belirtilmemiş, ancak geçerli, bu yüzden pop_backhala geçerli herhangi bir vektör gibi davranıyor (boş bir vektör bile olabilir).
Christian Rau

1
Bu bağlamda belirtilmemiş ve geçerli ne anlama geliyor?
Ankur S

114

17.6.5.15 [lib.types.movedfrom]

C ++ standart kütüphanesinde tanımlanan tipteki nesneler (12.8) 'den taşınabilir. Taşıma işlemleri açıkça belirtilmiş veya örtük olarak oluşturulmuş olabilir. Aksi belirtilmedikçe, bu tür taşınan nesneler geçerli ancak belirtilmemiş bir duruma yerleştirilecektir.

Bir nesne belirtilmemiş bir durumda olduğunda, nesne üzerinde önkoşulu olmayan herhangi bir işlemi gerçekleştirebilirsiniz. Gerçekleştirmek istediğiniz önkoşullara sahip bir işlem varsa, nesnenin belirtilmemiş durumunun önkoşulları karşılayıp karşılamadığını bilmediğiniz için bu işlemi doğrudan gerçekleştiremezsiniz.

Genellikle önkoşulu olmayan işlemlere örnekler :

  • imha
  • Görev
  • gibi const gözlemciler get, empty,size

Genellikle önkoşulları olan işlemlere örnekler :

  • KQUEUE
  • pop_back

Bu yanıt şimdi video biçiminde şu adreste görünüyor: http://www.youtube.com/watch?v=vLinb2fgkHk&t=47m10s


1
Ama önkoşulları diğer nesnelerde olduğu gibi kontrol edebilirim, değil mi?
fredoverflow 11:11

6
@FredOverflow Bu kontrollerin kendilerinin hiçbir ön koşulu olmadığı sürece, elbette.
Christian Rau

1
@Chris: Peki bu normal, taşınmamış bir nesneden nasıl farklı?
fredoverflow 11:11

2
Ayrı bir soru olabilir, ancak bu şu anlama gelir: char* buffer;ve int length;üyeleri ile bir dize varsa , o zaman benim hareket yapıcı / atama her ikisinin değerini takas (veya ayarla) gerekir? Ya da uzunluk belirtilmemiş olsaydı Tamam, (yani olurdu emptyve sizeanlamsız değerleri döndürür)?
amca

3
@ 6502: Bir anlam ifade etmiyorsun. Bir C ++ 03 sınıfı "C ++ 0x standardını ihlal etmez", çünkü oluşturulmuşsa bir taşıma kasası standardı ihlal eder. Ve C ++ 03 kodu bu sınıfı hareket ettirmeyecektir, bu nedenle bir taşıma torbasının üretilmesine gerek yoktur.
MSalters
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.