I need functionality that will be added in the next C++ version (C++17). I am using MS Visual Studio, which implements C++11. I expect that in a few years I'll upgrade my compilation tools, so this functionality will be available via the Standard library.
In the meantime, I need to implement it manually. How can I define it so it will be easy to migrate in the future?
Let's take std::clamp
as an example.
my_clamp
. When I am able to use C++17, I can start using std::clamp
, and optionally do a global replace of my_clamp
by std::clamp
. This looks ugly but probably will generate no surprises.my::std
, and do using namespace my
. This way, I can start using the name std::clamp
today, and not change it later. However, is it dangerous/forbidden?clamp
into std
namespace. This is UB, but will probably work.Is there a method without disadvantages?
Is there an accepted/customary way of doing this?
C++ Standard Library overview Provides an overview of the Microsoft implementation of the C++ Standard Library. iostream programming Provides an overview of iostream programming.
The g++ utility supports almost all mainstream C++ standards, including c++98 , c++03 , c++11 , c++14 , c++17 , and experimentally c++20 and c++23 . It also provides some GNU extensions to the standard to enable more useful features.
Master C and Embedded C Programming- Learn as you goC++98 − GCC has full support for the 1998 C++ standard as modified in 2003 and renamed to C++03 and some later defect reports. C++11 − GCC 4.8. 1 was the first complete implementation of the 2011 C++ standard, previously known as C++0x.
GCC has experimental support for the latest revision of the C++ standard, which was published in 2020. C++20 features are available since GCC 8.
What I usually do in these cases is:
1. try to use a recent C++ compiler and library that already includes the functions/facilities that I need.
2. failing that (i.e. I'm forced to stay with an older C++ standard version, let's say C++11, because of old toolchains), find a library that has what I need
3. better yet, if what I need is already included in a newer C++ standard or a "reference implementation" library already exists, I try to use the reference implementation or a close one, this will reduce future changes in your code.
4. get familiar with the boost library, as there may be a good chance that it already includes what you need, and it may well be the reference implementation for the future C++ standard stuff.
5. failing all the above, for whatever reason, write your own implementation, but try to keep its interface similar to the standard proposal.
For anything not coming from the std:: namespace, use namespace aliasing to further reduce future changes (when switching to newer toolchain and std:: ).
Note 1: C++17 IS the current C++ standard, the next should be C++20.
Note 2: MS VS2017 (and 2015 to some extent) already includes some or most of the stuff from C++17.
Edited to include an example of how to use namespace alias
This example is related to C++ filesystem stuff, it is not (yet) updated to use C++17 , but it's still limited to .
It mainly rely on preprocessor #defines (i.e. HAVE_CXX_EXPERIMENTAL_FILESYSTEM) to enable/disable the wanted portion.
I usually use CMake to detect compiler and library features and to define those macros in an automated fashion.
#if _MSC_VER >= 1900 // Microsoft Visual C++ 2015
#define HAVE_CXX_EXPERIMENTAL_FILESYSTEM
#endif
#if defined(HAVE_CXX_EXPERIMENTAL_FILESYSTEM)
// Have Filesystem TS
#include <experimental/filesystem>
namespace filesystem = std::experimental::filesystem;
using std::error_code;
#elif !defined(NO_BOOST)
// Fall-back to Boost.Filesystem library
#include <boost/version.hpp>
#if (BOOST_VERSION >= 103400)
#include <boost/filesystem.hpp>
#else
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/convenience.hpp>
#include <boost/filesystem/exception.hpp>
#endif // (BOOST_VERSION >= 103400)
namespace filesystem = boost::filesystem;
using boost::system::error_code;
// Hack to fix differences with C++17 Filesystem TS
#define copy_options copy_option
#define overwrite_existing overwrite_if_exists
#else
#warning Not implemented
// or #include custom stuff
#endif
What the above basically does is a fall-through:
1. use and alias the namespace if available
2. use boost.filesystem (if not explicitly excluded with NO_BOOST)
3. [optional] fallback to a custom implementation or other library if needed.
Disclaimer: this solution may not be perfect, but it's reasonably working for my needs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With