1

Some of the new features that have been added to the recent ISO C++ standards were originally part of boost. This naturally raises the question of guidelines for writing portable code.

Is there a canonical way to portably use new language features when using an older version of the standard?

If you are already using boost should you continue to use the boost versions or the versions in C++17 or the experimental versions?

How far should you go in trying to be portable?

I am surprised not to find this question as a FAQ somewhere. Shouldn't there be something about this in the core guidelines, the boost FAQ and or as an ISO committee paper?

There seem to be questions about individual features but less considering the wider view. For example:

Bruce Adams
  • 4,953
  • 4
  • 48
  • 111
  • The boost libraries are always more complete, more feature-rich and more portable than the standard libraries. Use boost. – Richard Hodges May 15 '18 at 10:56
  • 1
    "How far should you go" - calling for value judgment without context. This question solicits subjective answers. Use your own experience or that of your project members. – sehe May 15 '18 at 11:11
  • PS. I think the question would be viable for SO if it were focused on a very concrete topic (such as the linked "Aliasing boost::variant or std::variant not compilable") – sehe May 15 '18 at 11:14
  • @RichardHodges: ...more portable? You mean in old compiler support, or in platforms? – DevSolar May 15 '18 at 11:43
  • 1
    @DevSolar insofar as code written for one toolchain will work when compiled with another. dark corners of the standard tend to have differences and bugs in the various standard libraries (microsoft's non-standard handing of futures on destruction, apple's faulty regex library, etc). The boost team make a strong effort to keep cross-toolchain compatibility. Where they cannot, because of OS limitations or toolchain bugs, they document the differences well. – Richard Hodges May 15 '18 at 11:51
  • 2
    @DevSolar furthermore, the standard concurrency library is well behind that of boost.thread. There's a vague danger that we might finally get executors and future continuations in c++20... well over a decade after it was available in every other language. When boost features do finally make it to the standard, they are invariably chopped down to the point of uselessness (see thread, above). My advice, after writing c++ for 30 years, would be to standardise on the latest version of boost your compilers will bear - and keep upgrading. – Richard Hodges May 15 '18 at 11:57
  • @RichardHodges: Thank you for the elaboration, much appreciated. – DevSolar May 15 '18 at 12:10
  • The boost libraries may well be better but what happens if you also use another library which wants the same features and may itself provide or require polyfills? – Bruce Adams May 15 '18 at 13:40
  • There is no statement on the boost website saying "use boost instead of ISO". Would they feel comfortable with such a statement? I think a problem is that the choice varies between libraries and contexts. boost is a collection of libraries not just one. – Bruce Adams May 15 '18 at 13:42

1 Answers1

3

There are several projects that provide polyfills. Boost is not the only option, though it may be the most common and comprehensive. There are others, for example:

You can import the appropriate version with using clauses but this is risky as it masks semantic differences see also:

From boost to std::experimental and furthermore c++17

You might consider using feature test macros and create headers like "cxx17/optional.hpp" containing:

#ifdef __cpp_lib_experimental_optional
#include <experimental/optional>
namespace cxx17
{
using std::experimental::optional;
}
#elif __cpp_lib_optional
#include <optional>
namespace cxx17
{
using std::optional;
}
#else
#include <boost/optional.hpp>
namespace cxx17
{
using boost::optional;
}
#endif

However this still papers over semantic differences. In some cases the boost libraries deliberately differ from the standard.

You also have to consider that there is no such thing as portable code only code that has been ported. You cannot guarantee your code will work unless you have actually tested it in each environment.

If you attempt to make your code portable like this and have no intention of running it on those environments its just a YAGNI (you ain't gonna need it). Using the feature test macros shows you're clever but it could be considered noise if they aren't used.

If you are using boost already it seems safe to assume you can continue using it and leave it to boost (and the boost maintainers) to detect whether you are using C++17 or a TS and act according. Unless you have a lot of resources you can assume that the boost libraries are more portable than your code.

A good thing to do is to document intent. If you just want to make life easier for future maintainers but you are stuck using C++11 for now you might consider just doing (in cxx17/import_optional.hpp):

#include <boost/optional.hpp>
namespace cxx17
{
using boost::optional;
}

and using the cxx17 namespace to indicate that you wish to use C++17 but can't yet. This also implies that you consider deviations between boost and the ISO standard a bug for your project. Other users may just prefer the boost version. (consider for example What are the differences between std::variant and boost::variant?)

This applies mainly for pure library extensions. For changes to the language itself you can sometimes emulate them using macros. This can be ugly so it may be better to stick to a given standard.

This should probably be a community wiki but I will wait in case a more learned guru comes up with a better answer.

Bruce Adams
  • 4,953
  • 4
  • 48
  • 111
  • Not even a mention of abseil. (For the record, I upvoted the answer for the information, regardless of merit of the question :)) – sehe May 15 '18 at 11:13
  • Does abseil have anything specific to add here (other than https://abseil.io/about/philosophy)? I imagine if you use both abseil and boost this question just gets more complicated. – Bruce Adams May 15 '18 at 11:41
  • @BruceAdams I imagine the Abseil approach is roughly "this question is wrong, always compile at HEAD." – Barry May 15 '18 at 13:49
  • @barry I guess you are less of a fan than sehe :) – Bruce Adams May 15 '18 at 14:41
  • I have not ever touched Abseil. I guess that makes me the bigger fan then. Nobody mentioned "us[ing] both abseil and boost", I'd just note "Google has developed many abstractions that either match or closely match features incorporated into C++14, C++17, and beyond. Using the Abseil versions of these abstractions allows you to access these features now, even if your code is not yet ready for life in a post C++11 world." That makes it at least as relevant as any other library mentioned, I suppose. – sehe May 15 '18 at 15:06
  • @BruceAdams It's not a question of being a fan of abseil or not. That's just Titus' approach. It's not right or wrong, it's a valid approach. Just pointing it out. – Barry May 15 '18 at 15:21
  • Martin Moene has a bunch of standalone polyfill libraries that seem popular: https://github.com/martinmoene – Emile Cormier Feb 01 '23 at 03:41