Herb cevabı (düzenlemeden önceki) aslında bir tür iyi bir örnek verdi olmamalıdır hareket edebilir: std::mutex.
İşletim sisteminin yerel muteks türü (örneğin pthread_mutex_t, POSIX platformlarında) "konum değişmezi" olmayabilir, yani nesnenin adresi değerinin bir parçasıdır. Örneğin, işletim sistemi başlatılmış tüm muteks nesnelerine işaret edenlerin bir listesini tutabilir. Eğer std::mutex(OS onun muteksler işaretçilerin bir listesini tutar çünkü) olduğunda ya sabit kalan gereken bir veri üyesi ve yerli türünün adresi olarak bir doğal OS muteks türü içerdiği std::mutexo kalacaktı böylece yığın üzerinde yerli muteks türü saklamak zorunda kalacak std::mutexnesneler arasında hareket ettirildiğinde aynı konum veya std::mutexhareket etmemelidir. Yığın üzerinde saklamak mümkün değildir, çünkü bir std::mutexkurucuya sahiptir constexprve sürekli başlatma için uygun olmalıdır (yani statik başlatma), böylece globalstd::mutexprogramın yürütülmesi başlamadan önce oluşturulması garanti edilir, bu nedenle kurucusu kullanamaz new. Yani kalan tek seçenek std::mutextaşınmaz olmaktır.
Aynı mantık, sabit bir adres gerektiren bir şey içeren diğer türler için de geçerlidir. Kaynağın adresinin sabit kalması gerekiyorsa, hareket ettirmeyin!
Hareket etmemek için başka bir argüman std::mutexdaha var ki bu, bunu güvenli bir şekilde yapmanın çok zor olacağıdır, çünkü hareket edildiği anda hiç kimsenin muteksi kilitlemeye çalışmadığını bilmeniz gerekir. Muteksler, veri yarışlarını önlemek için kullanabileceğiniz yapı taşlarından biri olduğundan, yarışlara karşı güvenli olmasalar talihsiz olurdu! Bir taşınmaz ile, bir std::mutexkez inşa edildikten ve yok edilmeden önce, herhangi birinin ona yapabileceği tek şeyin onu kilitlemek ve kilidini açmak olduğunu bilirsiniz ve bu işlemlerin iş parçacığı açısından güvenli olduğu ve veri yarışları getirmediği açıkça garanti edilir. Aynı argüman std::atomic<T>nesneler için de geçerlidir : atomik olarak hareket ettirilmedikçe, onları güvenli bir şekilde taşımak mümkün olmazdı, başka bir iş parçacığı aramaya çalışıyor olabilircompare_exchange_stronghareket ettiği anda nesnenin üzerinde. Dolayısıyla, türlerin taşınabilir olmaması gereken başka bir durum, güvenli eşzamanlı kodun düşük seviyeli yapı taşları oldukları ve üzerlerindeki tüm işlemlerin atomikliğini sağlamaları gerektiği durumlardır. Nesne değeri herhangi bir zamanda yeni bir nesneye taşınabilirse, her atomik değişkeni korumak için bir atomik değişken kullanmanız gerekir, böylece onu kullanmanın güvenli olup olmadığını veya taşınmış olduğunu bilirsiniz ... ve korumak için bir atomik değişken bu atomik değişken ve benzeri ...
Sanırım bir nesne, bir değerin bir değerinin veya bir değerin soyutlamasının sahibi olarak hareket eden bir tür değil, yalnızca saf bir bellek parçası olduğunda, onu hareket ettirmenin bir anlam ifade etmediğini söyleyeceğim. intHareket edememe gibi temel türler : onları taşımak sadece bir kopyadır. Bağırsakları sökemezsiniz int, değerini kopyalayabilir ve sonra sıfıra ayarlayabilirsiniz, ancak yine intde bir değeri vardır, sadece bayt bellek. Ama inthala hareketlidil açısından, çünkü bir kopya geçerli bir taşıma işlemidir. Kopyalanamayan türler için, bellek parçasını hareket ettirmek istemiyorsanız veya hareket ettiremiyorsanız ve değerini de kopyalayamıyorsanız, o zaman taşınabilir değildir. Bir muteks veya bir atomik değişken, belleğin belirli bir yeridir (özel özelliklerle işlenir), bu nedenle taşınması mantıklı değildir ve aynı zamanda kopyalanamaz, bu nedenle taşınamaz.