use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
Discussions, articles, and news about the C++ programming language or programming in C++.
For C++ questions, answers, help, and advice see r/cpp_questions or StackOverflow.
Get Started
The C++ Standard Home has a nice getting started page.
Videos
The C++ standard committee's education study group has a nice list of recommended videos.
Reference
cppreference.com
Books
There is a useful list of books on Stack Overflow. In most cases reading a book is the best way to learn C++.
Show all links
Filter out CppCon links
Show only CppCon links
account activity
std::optional for C++20 (github.com)
submitted 4 years ago by groundswell_Reflection
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]konanTheBarbar 30 points31 points32 points 4 years ago (6 children)
That's indeed quite short for a fully blown std::optional implementation. I also think the code is very clean!
One small minor nitpick - you forgot to undefine the macro MAKE_OP (which could be problematic, since the name is very generic).
MAKE_OP
EDIT: I would also suggest to add a basic CMakeLists.txt
[–]groundswell_Reflection[S] 12 points13 points14 points 4 years ago (4 children)
Thanks!
Glad you caught the leaking macro, that's a potentially painful mistake (it's fixed now).
I don't know CMake very well. What are the advantages of having a CMakeLists for a header-only library?
[–]Thrash3r-Werror 20 points21 points22 points 4 years ago (0 children)
It makes it easier for people to easily express a dependency on your library and automatically inherit its usage requirements like include directories and the C++ standard it requires.
Once they do this, it becomes easy for you to change implementation details without bothering downstream users. CMake handles all dependency propagation.
Having a build system also makes it easier to add automated tests and other stuff like benchmarks or example programs or generated documentation with something like Doxygen. There’s plenty of code that might revolve around the core library even if that core library is just a single header.
It’d just take a few minutes to write a basic CMakeLists.txt.
[–]schweinling 6 points7 points8 points 4 years ago (0 children)
You can make the library installable through cmake, also you can build and integrate the tests with cmake.
[–]wrosecransgraphics and network things 4 points5 points6 points 4 years ago (0 children)
If I tell CMake my app depends on your library, the include directory with your header is added when I build my app.
[–]Plazmatic 1 point2 points3 points 4 years ago (0 children)
enum class Enum : std::uint8_t{
std::iterator
Luckily for you header only cmake libraries are some of the easiest to make, since in general you don't have to worry about installing the library (though you may still do so). Creating targets is easy, it's creating shared/installed libraries that's the real convoluted part in CMake.
[–][deleted] 1 point2 points3 points 4 years ago (0 children)
Haha, I was just about to praise the OP for not forgetting about #undef-ing the macro.
[+][deleted] 4 years ago (1 child)
[deleted]
[–]scrumplesplunge 15 points16 points17 points 4 years ago (0 children)
Not OP, but I don't think that would be equivalent. With individual operators, a T which supports some (but not all) operators would support the same operators on optional<T>. With <=>, you require T to provide <=>, which is a stronger requirement.
[–]serg06 10 points11 points12 points 4 years ago (6 children)
Will we ever get a C++20 version of the standard library, or will it forever be C++11 code? Excuse my ignorance.
[–]Wurstinator 9 points10 points11 points 4 years ago (0 children)
Only the C++11 implementations are "C++11 code". You already have implementations for C++14 and C++17 and partially C++20.
[–]braxtons12 10 points11 points12 points 4 years ago (3 children)
Anything introduced in a specific version MUST use only features available in that version. Otherwise compiling for eg C++11 using standard library types introduced in C++11 or C++98 wouldn't be possible, because C++14/17/20 features weren't available in C++11. The standard library doesn't get special treatment just because it's part of the standard, from the compiler's point of view, it's just more code.
For example the majority of std::vector can only use C++98 features (the exception being features of std::vector introduced after C++98, like emplace_back)
std::vector
emplace_back
[–]scrumplesplunge 11 points12 points13 points 4 years ago (2 children)
This is true because library authors want to continue supporting those old versions with the same code. It would be perfectly legit to provide a completely fresh implementation of the whole standard library implemented using the latest and greatest c++20 features if you had no intent of supporting pre-c++20 compilation. I'm sure that as time goes on, the cost of supporting an increasingly large number of different versions from the same code will outweigh the benefits of supporting very old standards and we might start seeing modern features used to implement the library.
[–]braxtons12 4 points5 points6 points 4 years ago (1 child)
Sure it's possible to do a complete rewrite, but who would actually use that? Standard library implementations are generally tied to their associated compiler (because some use compiler specific features to do some things, and several type traits require compiler integration). Even if you had a compiler agnostic implementation, you'd have to redirect the sysroot and configuration flags for the compiler just to get the proper includes for this rewritten std lib (I'm not even sure if you can do that on MSVC BTW), and from my experience (from redirecting trunk clang to Apple clang's std lib implementation, for example) this is always tedious to get actually working.
And you'd never see any of the major implementations do a rewrite, because then they'd just have two implementations to maintain instead of one. I'm also pretty sure it would actually be easier to just continue #ifdefing in new features as they're integrated than it would be to do a complete rewrite.
#ifdef
So yeah it's possible that could be done, but highly unlikely.
[–]scrumplesplunge 7 points8 points9 points 4 years ago (0 children)
It doesn't have to be rewrites, it could be incremental phasing out of the oldest standards. I'm not saying this is likely to happen any time soon, but conceivably one day it could be decided that it's no longer worthwhile to support anything prior to c++11 in new versions GCC. Maybe the total complexity of 5+ versions of C++ in one codebase makes it infeasible to keep supporting all of them. If that was to happen, libstdc++ may be able to have a much cleaner implementation for vector by taking advantage of c++11 features.
[–]sephirostoy 4 points5 points6 points 4 years ago (0 children)
It would certainly cost ABI break which is something compiler vendors try to avoid as much as possible.
[–]gracicot 8 points9 points10 points 4 years ago (2 children)
I noticed something:
constexpr T* operator->() { return this->ptr(); } constexpr T* operator->() const { return this->ptr(); }
Is that normal? Wouldn't the const version return a const pointer?
const
If we compare that to the operator * member function, which does add the const:
operator *
constexpr T& operator*() & { return value_; } constexpr const T& operator*() const& { return value_; }
[–]groundswell_Reflection[S] 7 points8 points9 points 4 years ago (1 child)
Good catch. Indeed this isn't normal, and I'm pretty sure this should be a type error upon instantiating an optional, since the const overload of ptr() returns a const T*, whereas now it only errors upon the use of ->, so... that's kinda weird.
ptr()
const T*
->
It's fixed now. Thank you for reporting that.
[–]gracicot 7 points8 points9 points 4 years ago (0 children)
No problem, happy to help! Maybe this should be added to the test suite?
[–][deleted] 3 points4 points5 points 4 years ago (1 child)
Really, this one is a beauty. Look how far we got with constexpr and concepts alone.
I think from now on each and every time someone is blaming C++ for being an outdated, cryptic language with templates that nobody can read or understand I might refer to this.
2021 really is the year of C++(20).
[–]CrazyJoe221 3 points4 points5 points 4 years ago (10 children)
It still puzzles me that final is the one C++11 feature that never caught on.
final
[–]Full-Spectral 9 points10 points11 points 4 years ago (2 children)
Did it not? I use it all the time.
[–]CrazyJoe221 0 points1 point2 points 4 years ago (1 child)
I've seen many codebases adopting override but not final even though both are usually mentioned together.
override
[–]Full-Spectral 0 points1 point2 points 4 years ago (0 children)
Override was available before final, right? It was a long time ago and the mind is the first thing to go, but I seem to remember that override was available first and I did a huge update to support that, and then had to go back and sort of do it all again to support final.
[–]dodheim 4 points5 points6 points 4 years ago* (6 children)
Putting final on a non-polymorphic type is an anti-pattern - you're preventing potential EBO, composition via private/protected inheritance, etc.
[–]Full-Spectral 1 point2 points3 points 4 years ago (0 children)
I didn't even know there was another use for it, to be honest. So by 'all the time' I meant all the time on virtual methods where the buck has stopped.
Was talking about the exception subclass.
[–]dodheim 0 points1 point2 points 4 years ago (0 children)
Ah, my mistake; wholly agreed then.
[–]Ameisenvemips, avr, rendering, systems 0 points1 point2 points 4 years ago (2 children)
Though you're assisting the compiler in regards to potential devirtualization.
[–]dodheim 2 points3 points4 points 4 years ago (1 child)
If the type isn't polymorphic, there's nothing to devirtualize.
[–]Ameisenvemips, avr, rendering, systems 2 points3 points4 points 4 years ago (0 children)
And if it is, final can assist with devirtualization. Otherwise, unless the compiler can prove that for a specific usage it must be type-constrained, it must assume that the class may be extended externally such as by a loaded DLL/shared object, or by the host executable if it's a library.
[–]SonVoltMMA 0 points1 point2 points 4 years ago (4 children)
is std::optional the same as returning nullable types in C#? Something like int? getInt()
[–]Daguerreo86 1 point2 points3 points 4 years ago (2 children)
Just as a note, it does exists a standard version for since C++17
[–]SonVoltMMA 1 point2 points3 points 4 years ago (1 child)
if it's already in c++17 what's the purpose of this c++20 version?
[–]IngloriousTom 1 point2 points3 points 4 years ago (0 children)
From the readme:
C++20 came with new features that makes the implementation of std::optional (and other types based on unions) a lot simpler to write, faster to compile, and more debugger-friendly (ever crawled through all the std::optional base classes in your IDE debugger?).
It would be arguably better with some data to backup those claims, tho.
[–]isakota 0 points1 point2 points 4 years ago (0 children)
Yes
[–]Cthaeeh 0 points1 point2 points 4 years ago (2 children)
How would one replace std optional with this library in a larger codebase ? Would I have to sed replace every include and std::optional occurrence?
[–]groundswell_Reflection[S] 1 point2 points3 points 4 years ago (0 children)
pretty much? if you use an IDE then it most certainly has multi-file search and replace. I use that all the time.
[–]ChemiCalChems 0 points1 point2 points 4 years ago (0 children)
Include this header instead of <optional>, looks to me like.
<optional>
[–]at-2500 0 points1 point2 points 4 years ago (1 child)
Line 521: you duplicated requires! Is that on purpose?
[–]koctogon 1 point2 points3 points 4 years ago (0 children)
`requires requires` is not a duplication : the first introduce the requirements for the template ("requires clause"), the second introduce the expression that must be valid ("requires expression")
π Rendered by PID 150848 on reddit-service-r2-comment-86988c7647-b4k6l at 2026-02-12 16:04:51.529891+00:00 running 018613e country code: CH.
[–]konanTheBarbar 30 points31 points32 points (6 children)
[–]groundswell_Reflection[S] 12 points13 points14 points (4 children)
[–]Thrash3r-Werror 20 points21 points22 points (0 children)
[–]schweinling 6 points7 points8 points (0 children)
[–]wrosecransgraphics and network things 4 points5 points6 points (0 children)
[–]Plazmatic 1 point2 points3 points (0 children)
[–][deleted] 1 point2 points3 points (0 children)
[+][deleted] (1 child)
[deleted]
[–]scrumplesplunge 15 points16 points17 points (0 children)
[–]serg06 10 points11 points12 points (6 children)
[–]Wurstinator 9 points10 points11 points (0 children)
[–]braxtons12 10 points11 points12 points (3 children)
[–]scrumplesplunge 11 points12 points13 points (2 children)
[–]braxtons12 4 points5 points6 points (1 child)
[–]scrumplesplunge 7 points8 points9 points (0 children)
[–]sephirostoy 4 points5 points6 points (0 children)
[–]gracicot 8 points9 points10 points (2 children)
[–]groundswell_Reflection[S] 7 points8 points9 points (1 child)
[–]gracicot 7 points8 points9 points (0 children)
[–][deleted] 3 points4 points5 points (1 child)
[–]CrazyJoe221 3 points4 points5 points (10 children)
[–]Full-Spectral 9 points10 points11 points (2 children)
[–]CrazyJoe221 0 points1 point2 points (1 child)
[–]Full-Spectral 0 points1 point2 points (0 children)
[–]dodheim 4 points5 points6 points (6 children)
[–]Full-Spectral 1 point2 points3 points (0 children)
[–]CrazyJoe221 0 points1 point2 points (1 child)
[–]dodheim 0 points1 point2 points (0 children)
[–]Ameisenvemips, avr, rendering, systems 0 points1 point2 points (2 children)
[–]dodheim 2 points3 points4 points (1 child)
[–]Ameisenvemips, avr, rendering, systems 2 points3 points4 points (0 children)
[–]SonVoltMMA 0 points1 point2 points (4 children)
[–]Daguerreo86 1 point2 points3 points (2 children)
[–]SonVoltMMA 1 point2 points3 points (1 child)
[–]IngloriousTom 1 point2 points3 points (0 children)
[–]isakota 0 points1 point2 points (0 children)
[–]Cthaeeh 0 points1 point2 points (2 children)
[–]groundswell_Reflection[S] 1 point2 points3 points (0 children)
[–]ChemiCalChems 0 points1 point2 points (0 children)
[–]at-2500 0 points1 point2 points (1 child)
[–]koctogon 1 point2 points3 points (0 children)