Hello, and welcome to C++ Weekly. I'm your host, Jason Turner.
In this episode I'm going to talk about a feature from C++20 which has surprising utility.
Be sure to check out the video description for links to my ebooks, printed books, Patreon
and Github sponsor page, as well as news about upcoming events that you might be interested in.
Now I think I can actually say this is going to be a very short episode - I know I often
start episodes with that statement and then they end up being not very short. So this is
feature test macros from C++20, and you can find it here in cppreference.com as always. C++20
standardized something that many compilers were already doing, and in a way it's a little ironic
that this is only added in C++20 because we could have used it certainly during the development of
11, 14 and 17 as well, but what this does is it gives you a compile time way of asking,
"Does this feature exist in the standard?" Every single feature added from C++11 forward has been
put in here, so you can even ask at compile time, "Does a certain attribute exist," or
"are 'binary literals' added?" and this is also an interesting way of just kind of discovering things
that were added to the standard and when. We can see here that was added in C++14, and this value
is the year and month that the proposal was actually accepted into the standard. So we can see
'attributes' were actually accepted in 2008. Some of the things that are slightly more surprising,
perhaps, are like 'delegating constructors' from 2006, and every now and then you'll stumble upon
a paper from C++20 that was actually accepted very early on in the proposal process such as
this thing from 2017 - "explicit template parameter list for generic lambdas," which
is a feature that I've covered on C++ Weekly. So I guess you know, right now
you could take a moment and comment and say, "Well, you haven't done a feature on x
yet. We would like to see that feature covered in an episode of C++ Weekly," so feel free to comment
on that in the comment section, although DO look to see if I've done an episode on it already
if you can take a moment to do that. Okay. So this isn't actually complicated, but it does cover
everything. Everything from C++11 forward. So I made use of this for the first time recently. I
have mentioned my tools repository a few times over the last couple of months, and it's just a
place where I've been putting things, and one of the things that we covered in a relatively recent
episode was this 'static_views' - this was that episode on the C++ constexpr problem that took me
five years to solve. So I have this 'static_views' header file here and this is how all things
are implemented. This is done in a generic way. It can be used with any C++20 compiler,
but not every C++20 compiler supports all of the features of C++20 yet; and I have my test here,
my 'static_views_test", and we can see down in here that I have this feature test macro - "if
_cpp_lib_constexpr_string", so I'm asking, "Does the standard library I'm currently using support
"constexpr string" usage?" You can see here I check to see if it's greater than or equal to
201907. I did not check for exact equality because it's entirely possible there will be multiple
versions of this value in the future if there's a future upgrade to "constexpr string" or something
like that, so I just look for is it this value or greater; and if it is then I know that I can
do tests that require constexpr string. It's 2022 right now, and I am trying to use a C++20 feature
with C++20 compilers. I pretty much only support the latest compilers here, so you might ask,
"Well, why is this even necessary?" Let's just go ahead and go to our handy "compiler support"
table from cppreference.com, and we can scroll down here to C++20 features, and,
here we go, we can see that actually libc++ is lagging a bit behind in C++20 library features. So
I wanted to support as many compilers as I could as best as I could; and we can see here
for "constexpr string" and "constexpr vector" we have full support in Visual Studio and GCC
but not yet in Clang. So this lets me compile my test on all the platforms although with a slightly
reduced test set when compiling on Clang with libc++. So there you go. This is the C++ feature
test macros from C++20. So before wrapping this up I decided to go ahead and do a quick review of
how and where and if actually checking that value matters to me, and we can see here
in this "_cpp_constexpr" feature macro we actually have 1, 2, 3, 4, 5, 6 different possible values
that it can be. So if all I care is that some minimal amount of C++11 constexpr support exists,
then I can check for greater than or equal to 200704. If I care that we've got all
of the features of "non-literal variables, labels, go to statements," etc from C++23,
then I'll need to check for this value or greater. So I do not think that I did overkill by checking
for greater than or equal to the particular number that I care about for that particular feature. So
check this out if you need it. Hopefully you can avoid it because this does rely on using
the C++ preprocessor, but it's there. It's a tool if you need it.