A small C++ meme dump
P0843 “inplace_vector
” (f.k.a. static_vector
, fixed_capacity_vector
);
P1144R8 §2.1.3.
See “P1144 case study: Moving a fixed_capacity_vector
” (2019-02-22)
and “Quuxplusone/SG14
now has inplace_vector
” (2023-10-20).
std::pmr::vector
either clears itself after move or not, depending on library vendor and
most importantly depending on whether the destination has the same arena. Neither criterion
relates to T
’s own triviality. (Godbolt.)
See also “A not-so-quick introduction to the C++ allocator model” (2023-06-02)
The math library for some reason has both
scalbn(double, int)
and scalbln(double, long int)
. Both functions simply add the int to the exponent
of the floating-point number (scaling its real value by \(2^n\)). For C compatibility, they also come
in float
flavor (scalbnf
, scalblnf
) and long double
flavor (scalbnl
, scalblnl
).
Presumably scalblnf
is useful on platforms where the number of bits in a float
’s
exponent field (e.g. 8) is greater than the number of bits in an int
(e.g. 32).
Cppreference describes scalblnf
and friends under the drippingly sarcastic heading
“Common mathematical functions.”
I don’t even know which way around this meme is supposed to go. a.merge(b)
does destructively modify b
(in that it pilfers all its nodes over into a
), so you might think a.merge(std::move(b))
correctly
indicates that this had better be the last use of b
. On the other hand, it reliably leaves b
empty,
not in some unspecified moved-from state — in fact, set::merge
leaves its right-hand argument in a reliably useful state! — and so the use of std::move
might be
philosophically incorrect. Certainly it’s more tedious to type out. I don’t know, man.
Sometimes people ask, if you can forward-declare a class template or a function template, why can’t you also forward-declare a concept?
template<class T> int f(T t); // OK
template<class T> class Mine; // OK
template<class T> concept Fungible; // ill-formed
The answer is that a function or class is usable without its definition: the compiler can deal with i = f(42)
or Mine<int> *p = nullptr
without knowing anything else about f
or Mine
. But to “use” a concept, you need
its definition.
template<class U> int g(U u) requires Fungible<U>;
Is g(42)
a valid function call? We don’t know unless we know the value of Fungible<int>
, which requires
seeing the definition of Fungible
. Forward-declaring concept Fungible
is useless. Therefore it’s
not allowed.
If you find yourself confused about the syntax of requires-expressions, or can’t think of how
to write a concept testing for a particular property, just remember that requires-expressions are
designed so that this works. (Including the sneaky behavior of Bar&&
above!)
Contrariwise, if you find yourself writing a lot of concepts that look like this meme,
consider maybe not writing those concepts at all: They likely aren’t doing anything except
to change the source location associated with your error messages.