How to determine the function that will be implemented in the next version of the standard library?

I need functionality that will be added in the next version of C ++ (C ++ 17). I use MS Visual Studio, which implements C ++ 11. I expect that in a few years I will update the compilation tools, so this functionality will be available through the standard library.

In the meantime, I need to execute it manually. How can I define it so that it can migrate easily in the future?

Take std::clamp as an example.

  • I can implement it with a different name, for example. my_clamp . When I can use C ++ 17, I can start using std::clamp and possibly do a global replacement of my_clamp with std::clamp . It looks ugly, but probably won't cause any surprises.
  • I can implement it in my namespace my::std and make using namespace my . That way, I can start using the name std::clamp today and not change it later. However, is it dangerous / forbidden?
  • I can somehow detect the C ++ version, and if it is less than 17, type clamp in the std . This is UB, but will probably work.

Is there a way without disadvantages?

Is there a common / usual way to do this?

+7
c ++ compatibility
source share
1 answer

What I usually do in these cases: 1. try using the recent compiler and C ++ library that already contain the functions / objects that I need.
2. Otherwise (that is, I have to stay with the old standard version of C ++, say C ++ 11, because of the old toolchains), find the library in which I need what I need 3. even better, if what I need is already included in the new C ++ standard or if the library of the "reference implementation" already exists, I'm trying to use a reference implementation or similar, this will reduce future changes in your code.
4. check out the boost library , as there may be a good chance that it already includes what you need, and there may well be a reference implementation for future standard C ++ material.
5. Having failed all of the above, for some reason, write your own implementation, but try to make its interface look like a standard offer.

For anything outside the std :: namespace, use a namespace alias to further reduce future changes (when switching to a newer toolchain and std: :).

Note 1: C ++ 17 is the current C ++ standard, the next should be C ++ 20.
Note 2: MS VS2017 (and to 2015 to some extent) already includes some or most of the materials from C ++ 17.

Edited to include an example using a namespace alias
This example is related to the C ++ file system, it has not yet been updated to use C ++ 17, but it is still limited.
This mainly depends on the #defines preprocessor (i.e. HAVE_CXX_EXPERIMENTAL_FILESYSTEM) to enable / disable the required part. I usually use CMake to detect compiler and library functions and to automatically detect these macros.

 #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 fail:
1. use a namespace alias if available
2. use boost.filesystem (unless explicitly excluding NO_BOOST)
3. [optional] backup to a custom implementation or other library, if necessary.

Disclaimer: This solution may not be perfect, but it works reasonably for my needs.

+2
source share

All Articles