2017-06-15 2 views
1

Ich benutze normalerweise Boost, um einige Funktionen zu implementieren, speziell das boost :: filesystem (1.58.0).Von boost zu std :: experimental und weiterhin C++ 17

Auch verwende ich std :: experimentell string_view (mein Compiler enthielt es nicht als Standard noch - g ++ 5.4.0 20.160.609).

Da die Boost-Funktionen, die ich verwende aprooved ich C++ 17 bereit sein will.

Fortunaly Ich verwende die folgenden Befehle in meinem Code:

using namespace boost::filesystem; //the only exeption is to boost::filesystem::remove 

using namespace std::experimental; 

Wenn ich die Boost-Leitung zu ‚using namespace std::experimental::filesystem;‘ ersetzen werde ich genau das gleiche Verhalten wie Boost-Implementierung mit Veränderungen nichts mehr in meinem Code bekommen?

Und nachdem ich den offiziellen gcc-Compiler bekommen mit diesen Merkmalen bereits standardmäßig enthalten alles, was ich brauchen, ist zu tun: a) ändert sich die ‚std::experimental::filesystem;‘ auf ‚std::filesystem‘ b) löschen die Zeile ‚using namespace std::experimental;

und bekomme das gleiche Verhalten mit Änderung nichts mehr in meinem Code?

Welche anderen Boost-Funktionen sind in C++ 17 enthalten und können auch einfach wie oben beschrieben ersetzt werden?

+0

Während einige der neuen Funktionen auf Boost-Bibliotheken basieren oder von diesen inspiriert sind, gibt es möglicherweise keine Eins-zu-Eins-Übersetzung der Boost-Bibliotheken in die Standardbibliothek. Mit dem gesagt, bezweifle ich, dass es etwas Großes oder Gemeines geben wird, das geändert wurde (wenn überhaupt), so dass Sie in der Lage sein sollten, 'std :: filesystem' genauso wie die Boost-Dateisystem-Bibliothek zu verwenden. –

+2

Boost-Dateisystem und Boost-Threads sind die einzigen beiden, von denen ich weiß, dass sie versuchen, die Standardvorschläge zu verfolgen. Dies wird sofort durch die Tatsache reflektiert, dass sie viele brechende Änderungen in der öffentlichen Schnittstelle haben (Boost Dateisystem v2/v3, und Boost Thread verwendet ein Dutzend wichtige bedingt kompilierte Merkmalsauswahlmakros) – sehe

Antwort

4

Boost ist nicht (verbunden mit dem) ISO-Standard.

Nein, Sie sollten nicht blind erwarten, dass die Semantik identisch ist. Obwohl in 80% -90% der Fälle die Schnittstelle kompatibel sein wird, werden Sie Unterschiede bekommen.

z. boost::optional<T&> ist erlaubt, aber nicht in der Standardversion. Es gibt andere Unterschiede.

Im Allgemeinen ist es eine schlechte Praxis using-directives zu verwenden, vor allem, wenn Sie es auf Papier dieser Unterschiede verwenden. Wenn Sie Ihre Abhängigkeiten mobil halten möchten, sollten Sie am besten eigene Namespaces und Wrapper-Funktionen erstellen.

In meiner Code-Basis, z.B. Ich habe

namespace XXX { 

    using nullopt_t = ::boost::none_t; 
    static CONSTEXPR nullopt_t nullopt = {}; 

    template <typename T> using optional = ::boost::optional<T>; 
} 

Wir ausschließlich in jedem Nicht-Boost-spezifischen Code verwenden diese Schnittstelle verwendet.

Dies sollte bei der Umstellung auf die Standardbibliotheksversion helfen, mit Ausnahme der bereits erwähnten semantischen Unterschiede.

+0

Ich verstehe, warum ist nicht eine gute Praxis zu verwenden Direktiven mit externen Bibliotheken wie Boost Auch ich lese es ist nicht gut, um mit Std zu verwenden "using namespace std;" und ich verstehe nicht warum. – Tecoberg

+3

Es ist offensichtlich eine Wahl. Die Verwendung von Direktiven in Headern ist selten eine gute Sache, da sie Namenskollisionen einlädt und aufgrund von z.B. ADL. (Die erwähnenswerte Ausnahme sind Inline-Namespaces und Versionierung, denke ich). Siehe z.B. [Warum Namespace std als schlechte Praxis verwendet wird] (https://stackoverflow.com/questions/1452721/why-isusing-namespace-std-considered-bad-practice) – sehe

+0

In diesem Fall war ich motivierend _why_ es ist nicht eine zuverlässige Möglichkeit, Implementierungen zu wechseln: Die Spezifikationen sind nicht austauschbar. – sehe

1

Boost und die später abgeleiteten Standardisierungen neigen dazu, sich zu unterscheiden.

Im Falle von Dateisystem gibt es ein paar brechende Änderungen. Aus der Spitze meines Kopfes wurde eine Flagge in ein kleines Flaggenfeld verwandelt.

Allerdings funktionieren 90% des Codes gleich.

Statt using namespace boost::filesystem; betrachten

mit
#ifdef USE_BOOST_FILESYSTEM 
    namespace filesystem = boost::filesystem; 
#else 
    namespace filesystem = std::experitmental::filesystem; 
#endif 

filesystem:: jetzt Ihre Nutzung der API Präfix verwenden.

An der Handvoll Spots, wo die Implementierung unterscheidet, können Sie mehr #ifdef verwenden.

Die Dinge, die in diesem Namespace sind, stechen jetzt in Ihrem Code hervor, und Sie haben eine #ifdef, um die Ecke Fälle zu behandeln, wo sie nicht kompatibel sind.

Verwandte Themen