Testaamme kirjastoa C ++ 11: ssä (ts. -std=c++11). Kirjasto käyttää auto_ptr ja tätä mallia: 
Foo* GetFoo() { autoptr<Foo> ptr(new Foo); // Initialize Foo ptr->Initialize(...); // Now configure remaining attributes ptr->SomeSetting(...); return ptr.release(); } 
 C ++ 11 vanhentunut auto_ptr, joten haluamme siirtyä pois siitä. 
 Koodi kuitenkin tukee sekä C ++ 03: ta että C ++ 11: tä, joten se ei ole yksinkertainen kuin yanking auto_ptr. On myös syytä mainita, että kirjastolla ei ole ulkoisia riippuvuuksia. Se käyttää C ++ 03: ta eikä käytä Autotools-, Cmake-, Boost-, … 
 Kuinka meidän tulisi käsitellä suunnittelumuutoksia siirtyäksesi pois auto_ptr mallille C ++ 11 säilyttäen yhteensopivuus C ++ 03: n kanssa? 
Kommentit
Vastaa
 Useimmiten  std::unique_ptr  tehtiin pudotettavaksi (mutta turvallisempi)  std::auto_ptr  -korvaus, joten koodimuutoksia, joita vaaditaan, on oltava hyvin vähän muuten kuin mahdollista (kun kysyt) ohjaamalla koodi käyttämään joko unique_ptr tai auto_ptr. 
On olemassa muutama tapa tehdä tämä (ja jokaisella on omat listansa kompromissit) alla. Annetun koodinäytteen perusteella suosittelen kahta ensimmäistä vaihtoehtoa .
Vaihtoehto 1
#if __cplusplus >= 201103L template <typename T> using auto_ptr = std::unique_ptr<T>; #else using std::auto_ptr; #endif 
Kompromissit;
-  Lisää 
auto_ptr-nimi globaaliin nimiavaruuteen ; voit lieventää tätä määrittelemällä, että se on oma " yksityinen " nimiavaruus -  Kun olet siirtänyt C ++ 17: een (Uskon, että 
auto_ptrpoistetaan kokonaan). Voit etsiä ja korvata helpommin. 
Vaihtoehto 2
template <typename T> struct my_ptr { #if __cplusplus >= 201103L typedef std::unique_ptr<T> ptr; #else typedef std::auto_ptr<T> ptr; #endif }; 
Kompromissit;
-  Todennäköisesti hankalampi työskennellä, kaikki nykyiset 
auto_ptron muutettava koodissa jotainmy_ptr<T>::ptr - Paremman turvallisuuden vuoksi nimiä ei lisätä globaaliin nimiavaruuteen
 
Vaihtoehto 3
 Hieman kiistanalainen, mutta jos olet valmis sietämään varoitukset siitä, että std -luokka on perusta 
#if __cplusplus >= 201103L template <typename T> using my_ptr = std::unique_ptr<T>; #else template <typename T> class my_ptr : public std::auto_ptr<T> { // implement the constructors for easier use // in particular explicit my_ptr( X* p = 0 ) : std::auto_ptr(p) {} }; #endif 
Kompromissit;
- Älä yritä käyttää perittyä luokkaa, jossa virtuaalisen tukikohdan (erityisesti kirjoitetun ei-virtuaalisen tuhoajan) odotetaan olevan. Ei, että tämän pitäisi olla asia – mutta ole tietoinen siitä
 - Koodimuutokset jälleen
 - Mahdolliset nimiavaruudet eivät täsmää – kaikki riippuu siitä, miten osoitinluokka aloitetaan
 
Vaihtoehto 4
Kääri osoittimet uuteen luokkaan ja koota tarvittavat toiminnot jäsenelle
template <typename T> class my_ptr { // could even use auto_ptr name? #if __cplusplus >= 201103L std::unique_ptr<T> ptr_; #else std::auto_ptr<T> ptr_; #endif // implement functions required... T* release() { return ptr_.release(); } }; 
Kompromissit;
- A vähän äärimmäistä, kun kaikki mitä todella haluat, on " vaihtaa " toteutukset ulos
 
kommentit
- Erittäin hyvä vastaus. Tutkin itse asiassa sitä vähän, ja osui ainakin kolme testistä, jotka yritin. (Sinulta puuttuu OS X- ja Clang-spesifisiä juttuja. OS X on karhu, koska se käyttää silti ajoittain TR1-nimitilaa C ++ 03: lle, ja sinun on sisällytettävä asiat tällä menetelmällä: Ei tyyppiä nimeltä ' unique_ptr ' nimitilassa ' std ' käännettäessä LLVM / Clangissa ).
 -  @jww. <
 
 m OS X: ssä (XCode 6.4 ja Apple LLVM -versio 6.1.0 (clang-602.0.53) (perustuu LLVM 3.6.0svn: iin)) ja minulla ei ole ongelmia C: n kanssa ++ 03/11 sekoitus, joka ei ole muu kuin tr1 -nimitila (en käytä libc ++ eikä libstdc ++).Tiedän, että tr1 ei ollut normatiivista, mutta en voi ' löytää mistään  -luonnoksesta (täällä) , että tiedostojen piti olla lainkaan <tr1/...>, infact mainitsee vain olevan otsikossa <memory> jne. vain tr1 nimiavaruus. 
CXX=...). c++ -v -std=c++11 -x c++ - < /dev/null. grep'd sisällytän tyhjennetyt hakemistot, ja ne  eivät  sisältävät unique_ptr. vastaus
Vaihtoehto 5: Suora alias.
#if __cplusplus >= 201103L template<typename T> using MyPtr = std::unique_ptr<T>; #else #define MyPtr std::auto_ptr #endif 
Kompromissit:
- 
Uudemmille kieliversioille, AKA C ++ 11 ja uudemmat, alias-tyyppisi yhdistää oikean älyosoittimen. Kääntäjä merkitsee kaikki käyttäjäkoodit, jotka tosiasiallisesti riippuvat tavalliselle standardille :: auto_ptr määritetyistä sovellusliittymistä, mikä takaa lopullisen korjauksen.
 - 
Vanhassa versiossa c ++ 03-tilassa tyypin alias on makro. Tämä on karkea, mutta tuloksena syntaksin
MyPtr<T>tulee olemaan identtinen C ++ 11 -tapahtuman kanssa koko koodissa. / p> - 
Sinun on löydettävä ja muutettava kaikki auto_ptr-muuttujat
MyPtr-asetuksiksi tämän määrittämiseksi. 
Kommentit
- ' on hyvin epäselvää, mihin tämä viittaa (ja kuten sanottu se ei ole lainkaan ' ta kysymys).
 - @autophage uskon sen vastauksen … joten luultavasti ei kysymys.
 
auto_ptr-luokitelluista alueista (ts.std::auto_ptr), onko niiden oltava vai voidaanko älykäs osoitin saada jostakin muusta nimiavaruudesta?Foo::InitializeosaksiFoo::Foo.