cppreference.com says:
In practice, implementations of std::copy avoid multiple assignments and use bulk copy functions such as std::memmove if the value type is TriviallyCopyable
However, the page also states that the overloads which don't take an execution policy will be constexpr
since C++20. Will the standard forbid these run-time optimizations (since std::memmove
is not constexpr) or is there a way to optimize constexpr
functions for run-time?
We can have our cake and eat it to, too.
Let's just consider the simplest specialization of copy
, the one that copies char
s. In C++17, that might look like:
char* copy(char const* first, char const* last, char* d)
{
memcpy(d, first, last - first);
return d + (last - first);
}
Of course, we can't just slap constexpr
on that because memcpy
isn't a constexpr function, that won't work. But it only doesn't work during constant evaluation. What we need is a way to conditionally use memcpy
if we're at runtime.
We have such a thing in C++20, std::is_constant_evaluated()
:
constexpr char* copy(char const* first, char const* last, char* d)
{
if (std::is_constant_evaluated()) {
while (first != last) {
*d++ = *first++;
}
return d;
} else {
memcpy(d, first, last - first);
return d + (last - first);
}
}
And now we have an algorithm that does the efficient thing at runtime but still works during constexpr evaluation time.
Note: It is if (std::is_constant_evaluated())
, never if constexpr (std::is_constant_evaluated())
. The later is equivalent to if constexpr (true) { ... }
. gcc 10.1 will start warning on this erroneous usage.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With