Compile-time sizes for range adaptors
Foonathan Blog
by
8M ago
In my previous blog post, we’ve discussed the static constexpr std::integral_constant idiom to specify the size of a range at compile-time. Unlike the standard, our (think-cell’s) ranges library at think-cell already supports compile-time sizes natively, so I was eager to try the idiom there and see how it works out in practice. namespace tc { template <typename Rng> constexpr auto size(Rng&& rng); // runtime-size of a range, like std::ranges::size template <typename Rng> requires tc::has_constexpr_size<Rng> constexpr auto constexpr_size = …; // com ..read more
Visit website
The new static constexpr std::integral_constant idiom
Foonathan Blog
by
8M ago
The size of std::array<T, N> is known at compile-time given the type. Yet it only provides a regular .size() member function: template <typename T, std::size_t N> struct array { constexpr std::size_t size() const { return N; } }; This is annoying if you’re writing generic code that expects some sort of compile-time sized range ..read more
Visit website
Should we stop writing functions?
Foonathan Blog
by
9M ago
… and use lambdas instead? That is, instead of: int sum(int a, int b) { return a + b; } You’d write: constexpr auto sum = [](int a, int b) -> int { return a + b; }; Hear me out ..read more
Visit website
Constrain your user-defined conversions
Foonathan Blog
by
10M ago
Sometimes you want to add an implicit conversion to a type. This can be done by adding an implicit conversion operator. For example, std::string is implicitly convertible to std::string_view: class string { // template omitted for simplicity public: operator std::string_view() const noexcept { return std::string_view(c_str(), size()); } }; The conversion is safe, cheap, and std::string and std::string_view represent the same platonic value — we match Tony van Eerd’s criteria for implicit conversions and using implicit conversions is justified. However, even when all crite ..read more
Visit website
Technique: Proof types to ensure preconditions
Foonathan Blog
by
1y ago
Consider a library using hidden global state that needs to be initialized by calling an initialization function. If you don’t call the function before you start using the library, it crashes. How do you design the library in such a way that it is impossible to use it before initialization? One idea is to use a technique where you create a special proof type, which needs to be passed as an additional parameter. Let’s look at it in more detail ..read more
Visit website
New integer types I'd like to see
Foonathan Blog
by
1y ago
(Most) C++ implementations provide at least 8, 16, 32, and 64-bit signed and unsigned integer types. There are annoying implicit conversions, discussions about undefined behavior on overflow (some think it’s too much UB, others think it’s not enough), but for the most part they do the job well. Newer languages like Rust copied that design, but fixed the conversions and overflow behavior. Still, I think there is room for innovation here. Let me talk about three new families of integer types I’d like to see ..read more
Visit website
Malloc() and free() are a bad API
Foonathan Blog
by
1y ago
If you need to allocate dynamic memory in C, you use malloc() and free(). The API is very old, and while you might want to switch to a different implementation, be it jemalloc, tcmalloc, or mimalloc, they mostly copy the interface. It makes sense that they do that – they want to be a mostly drop-in replacement, but it’s still unfortunate because malloc() and free() are a bad API for memory allocation. Let’s talk why ..read more
Visit website
Carbon's most exciting feature is its calling convention
Foonathan Blog
by
1y ago
Last week, Chandler Carruth announced Carbon, a potential C++ replacement they’ve been working on for the past two years. It has the usual cool features you expect from a modern language: useful generics, compile-time interfaces/traits/concepts, modules, etc. – but the thing I’m most excited about is a tiny detail about the way parameters are passed there. It’s something I’ve been thinking about in the past myself, and to my knowledge it hasn’t been done in any low-level language before, but the concept has a lot of potential. Let me explain what I’m talking about ..read more
Visit website
Tutorial: Preparing libraries for CMake FetchContent
Foonathan Blog
by
1y ago
If you’re working on an executable project in C++, as opposed to a C++ library, using a package manager to get your dependencies might be overkill: If all you need is to get the source code of a library, include in your CMake project, and have it compiled from source with the rest of your project, CMake’s FetchContent module can do it for you. If you’re a library writer, there are ways you can structure your CMake project to improve the experience for end users that use FetchContent: hide developer targets like tests, provide a zip archive that contains only the source files relevant downstrea ..read more
Visit website
Technique: Recursive variants and boxes
Foonathan Blog
by
2y ago
There are many data structures that can be elegantly expressed using sum types. In C++ a (somewhat clunky) implementation of sum types is std::variant. However, it can’t handle recursive data structures, where one alternative contains the entire sum type again. Let’s see how we can fix that ..read more
Visit website

Follow Foonathan Blog on FeedSpot

Continue with Google
Continue with Apple
OR