j'ai donc une cow_ptr
simple. Il ressemble à ceci:copie à l'écriture avec shared_ptr
template<class T, class Base=std::shared_ptr<T const>>
struct cow_ptr:private Base{
using Base::operator*;
using Base::operator->;
using Base::operator bool;
// etc
cow_ptr(std::shared_ptr<T> ptr):Base(ptr){}
// defaulted special member functions
template<class F>
decltype(auto) write(F&& f){
if (!unique()) self_clone();
Assert(unique());
return std::forward<F>(f)(const_cast<T&>(**this));
}
private:
void self_clone(){
if (!*this) return;
*this = std::make_shared<T>(**this);
Assert(unique());
}
};
ce qui garantit qu'il est titulaire d'un non-const T
et assure qu'il est unique
quand il .write([&](T&){})
s à elle.
La désapprobation c++17 de .unique()
semble indiquer que cette conception est erronée.
Je suppose que si nous commençons par un cow_ptr<int> ptr
avec 1
en fil A, passer à fil B, le rendre unique, le modifier à 2
, passer ptr
en arrière et lire en fil A
nous avons généré une course condition.
Comment résoudre ce problème? Puis-je simplement ajouter une barrière de mémoire dans write
? Laquelle? Ou le problème est-il plus fondamental?
sont des symptômes moins probable sur x86 en raison de la cohérence de la mémoire x86 allant au-delà de ce que demande C++?