Bir tür yapmak için zaman hareketli olmayan C 11'de?
Bu arama sonuçları, birisi daha önce C 11'de hareket semantiği kullanışlılığını belirli istedi diye düşündüm gözükmedi mi şaşırdım:
Ne zaman (ya da benim için iyi bir fikir olduğunu) C sınıfı 11-menkul olmayan yapmak zorunda mıyım?
(Sebepdiğermevcut kod ile uyumluluk sorunları daha.)
CEVAP
Herb cevabı düzenlendiği önce) aslında bir tür iyi bir örnek verdiolmamalıolması hareketli: std::mutex
.
İşletim sistemi yerel zaman uyumu sağlayıcısı türü (pthread_mutex_t
örneğin POSIX platformlarda)" nesnenin adresi anlamı değeri parçasıdır. değişmeyen "konumu olmayabilir Örneğin, işletim sistemi her başlatılmış dışlama nesnelere işaretçiler bir listesini tutmak olabilir. std::mutex
bulunan bir yerli OS dışlama türü bir veri üyesi ve yerel türü Adres kalmak gerekir sabit (çünkü işletim sistemi korur listesi işaretçileri olan uyumu) sonra da std::mutex
... mağaza yerel zaman uyumu sağlayıcısı türü öbek öyle kal aynı konuma taşındığında arasında std::mutex
nesneleri veya std::mutex
olmalı değil hareket. Depolama üzerine öbek mümkün değil, çünkü bir std::mutex
constexpr
yapıcı olmalı hak için sabit başlatma (yani statik başlatma) böylece küresel std::mutex
garantili inşa önce programın yürütme başlar, bu yüzden onun kurucu kullanamazsınız new
. Tek seçenek sol std::mutex
taşınmaz olmak için.
Aynı mantık, sabit bir adresi gerektiren şeyler içeren diğer türleri için geçerlidir. Eğer kaynak adresi sabit kalmasını, hareket ettirme!
Orada başka bir tartışma için hareket etmiyor std::mutex
ki bu çok zor bunu yapmak için güvenli bir şekilde, çünkü edeceğini bilmek kimse ulaşmaya çalışıyor kilit dışlama şu anda onu transfer ediliyor. Zaman uyumu sağlayıcılar veri yarışları önlemek için kullanabilirsiniz taşlarından biri olduğu için, eğer yarış karşı kendilerini güvende değillerse yazık olur! Taşınmaz std::mutex
bildiğiniz tek şey herkes yapabilir bunu bir kez inşa edilmiş ve daha önce tahrip olmuştur olduğu için kilit ve kilidini açmak ve bu işlemler açıkça garantili iş parçacığı güvenli değil tanıtmak veri yarışları. Bu aynı argüman için geçerlidir std::atomic<T>
nesneler: sürece olabilirler taşındı atomik olmaz Olası güvenle hareket, başka bir iş parçacığı olabilir aramaya compare_exchange_strong
nesneye doğru anda transfer ediliyor. Bu yüzden tür hareketli olması gereken yerde başka bir dava daha düşük düzeyde olduğu güvenli eşzamanlı kod blokları inşa ediyor ve onlara tüm işlemleri katına çıkar sağlamak gerekir. Eğer nesne değeri olabilir taşındı için yeni bir nesne herhangi bir zamanda Zorundasınız kullanın atomik değişken korumak için her atom değişken çok biliyorsan güvenli kullanacağını ya da taşındı ... ve bir atom değişken koruyan atom değişken.
Bence genelleme olur ki o zaman bir nesne sadece bir parça saf bellek, bir tür davranır gibi bir sahibi için bir değer ya da soyut bir değer, ama bu çok anlamsız hareket. int
gibi temel türleri hareket edemiyor: taşımadan sadece bir kopyasıdır. Sen rip bağırsakları dışarı int
, kopya değeri ve set sıfır, ama hala bir int
ile bir değer, sadece bayt bellek. Ama bir int
halahareketlibir kopya çünkü dil açısından geçerli bir taşıma işlemi. İstemiyorum ya da bellek parçası hareket edemez ve sen de onun değerini kopyala yapamazsan olmayan copyable türleri için, ancak daha sonra non-hareketli. Bir dışlama ya da atom değişken mantıklı hareket etmiyor ve de copyable kadar bellek (özel özellikleri ile tedavi) belirli bir yerde, olmayan taşınır.