Exception-aware malloc version of make_unique - c++11

In C++11 there is no make_unique (can't use C++14), although one can quickly be mocked up like so (plenty of answers already out there suggest something like this):
template< typename T, typename ... Args >
std::unique_ptr< T > my_make_unique (Args && ... args) {
return { new T( std::forward< Args >( args )... ) };
}
This is fine if the desired result is for new / delete to be invoked on typename T. In my case it's not because I'm overriding global new / delete, which internally will (where convenient) use unique_ptr. So instead I'm using malloc and various wrappers & allocators based on malloc to make STL containers work without extra bloat at the site of usage. I was doing fine with this approach until exceptions came along...
Building on the answers in this question so far I have this as a possible generic solution:
template< typename T >
struct destroy_free {
void operator() (void * p) {
if ( !p ) return;
static_cast< T* >( p )->~T();
free( p );
}
};
template< typename T, typename ... Args >
auto malloc_make_unique (Args && ... args) -> std::unique_ptr< T, destroy_free< T > > {
if ( auto ptr = malloc( sizeof(T) ) )
return { new ( ptr ) T( std::forward< Args >( args )... ) };
return { nullptr }; // global new would throw bad_alloc here.
}
This seems ok but exception handling is totally ignored here with regard to how new (ptr) T(...) would work, as opposed to new T(...), and how this affects any version of make_unique especially when using a custom allocation method.
For a start, I'm aware throwing std::bad_alloc is ill advised, however I believe the principle of least surprise applies here and it's forgivable to emulate what new would do (ie, throw when allocation fails as opposed to returning nullptr). This begs two questions.
1. Is it justifiable to replace return { nullptr } with throw std::bad_alloc()?
2. To correctly replicate new T(...)'s behavior, if the constructor throws then the exception needs to be caught, so the memory can be released immediately and then rethrow the constructor exception?
Assuming yes to both, is the below handling the situation correctly or is there anything else to consider?
template< typename T, typename ... Args >
auto malloc_make_unique_v2 (Args && ... args) -> std::unique_ptr< T, destroy_free< T > > {
if ( auto ptr = malloc( sizeof(T) ) ) try {
return { new ( ptr ) T( std::forward< Args >( args )... ) };
} catch( ... ) { // catch constructor exceptions
// assumed: memory allocated but object not constructed
free( ptr ); // release memory, object was not constructed?
throw; // propagate whatever the exception was during construction?
}
throw std::bad_alloc(); // no memory allocated, throw bad_alloc?
}
edit - please note I'm ignoring alignment for simplicity.

Assuming yes to both, is the below handling the situation correctly or is there anything else to consider?
Looks ok to me.
There is std::allocate_shared which creates shared_ptr with object memory allocated by custom allocator. What you are making is essentially allocate_unique which does not exist (perhaps, yet) in standard c++. Maybe you could create custom allocator that uses malloc/free and then implement your own make_unique (if you don't have it) and allocate_unique.

Related

the return of function "if constexpr" and "else if constexpr"

I'm the beginner with C++.
Could some one explain the output after compile process function.
Thanks a lot.
template <typename T>
auto process(T arg)
{
// 4. With constexpr if, to enable the compiler to generate different code based on the type the template is instantiated with:
if constexpr (std::is_same<T, bool>::value)
return !arg;
else if constexpr (std::is_integral<T>::value)
return -arg;
else if constexpr (std::is_floating_point<T>::value)
return std::abs(arg);
else
return arg;
}
int main(){
...
{
auto v1 = process(false); // true
auto v2 = process(42); // -42
auto v3 = process(-42.0); // 42.0
auto v4 = process("42"s); // "42"
}
...
return 0;
}
what's the real code compiler for process() is generated after we call above code in main function.
what's the real code compiler for process() is generated after we call above code in main function.
process() is not a function, and no compiled version of it is produced (at least in typical implementations); rather, your program produces four separate functions, namely process<bool>, process<int>, process<double>, and process<std::string>, each of which has its own compiled version.
And that's not specific to if constexpr — it's just how templates work in general in C++.
Those compiled versions can completely omit the branches of the if statement that don't hold for the type argument; so, for example, process<bool> is as if it were defined like this:
template<>
bool process<bool>(bool arg)
{
return !arg;
}

C++11 Variadic function in variadic template class not working as expected

Sincere apologies if this has been answered elsewhere, I did search but couldn't find a clear match.
I have a variadic function in a template class that does not work exactly as I expected. I have a workaround, but I suspect it's not the best solution.
Consider the following code:
#include <iostream>
#include <functional>
#include <vector>
template< typename... ARGS >
class Kitten
{
public:
using Callback = std::function< void( ARGS&&... ) >;
Kitten() = default;
void addCallback( Callback && c )
{
callbacks.push_back( std::forward< Callback >( c ) );
}
void processCallbacks( ARGS &&... args )
{
for ( Callback const &c : callbacks )
{
c( std::forward< ARGS >( args )... );
}
}
private:
std::vector< Callback > callbacks;
};
int main( int argc, const char * argv[] )
{
( void ) argc;
( void ) argv;
Kitten<int, float> kitty;
kitty.addCallback( []( int i, float f )
{
std::cout << "Int: " << i << "\nFloat: " << f << "\n";
} );
kitty.processCallbacks( 2, 3.141f );
int ii = 54;
float ff = 2.13f;
kitty.processCallbacks( ii, ff );
return 0;
}
This will not compile, the second call to processCallbacks will generate an error (clang, similar issue seen on vc14).
I can fix the compilation and get things working as expected if I change the definition of processCallbacks to:
template< typename... FORCEIT >
void processCallbacks( FORCEIT &&... args )
{
for ( Callback const &c : callbacks )
{
c( std::forward< ARGS >( args )... );
}
}
It seems to me to be a bit of a cheesy workaround even if it seems to work, and I suspect I'm missing a better solution.
My understanding of why the first sample fails is because there's no type deduction being done on the argument pack, so the compiler isn't generating the correct code for all cases. The second sample works because it forces the type deduction on the argument pack.
It's been puzzling me for a while on and off. Any help much appreciated.
edit: vc12 compiler error:
error C2664: 'void Kitten<int,float>::processCallbacks(int &&,float &&)' : cannot convert argument 1 from 'int' to 'int &&'
edit: Apple LLVM version 7.0.0 compiler error:
error: rvalue reference to type 'int' cannot bind to lvalue of type 'int'
Regarding the change suggested in the comments to use std::move, addCallback would seem to be even more flexible in the form:
template< typename FUNCTION >
void addCallback( FUNCTION && c )
{
callbacks.emplace_back( std::forward< FUNCTION >( c ) );
}
Using std::forward because the function now takes a universal reference.
As this would allow the following to work:
std::function< void( int, float )> banana( []( int i, float f )
{
std::cout << "Int: " << i << "\nFloat: " << f << "\n";
} );
kitty.addCallback( banana );
void processCallbacks( ARGS &&... args )
{
//...
}
For each type in ARGS the allowed value categories will be set by the template arguments to Kitten. E.g. for Kitten<float, int&, const bool&>, processCallbacks will accept rvalues for the first parameter, lvalues for the second (due to reference collapsing rules) and both for the third (because rvalues can bind to const lvalue references). This will not give you perfect forwarding.
template< typename... FORCEIT >
void processCallbacks( FORCEIT &&... args )
{
//...
}
That function template accepts both lvalues and rvalues because there is type deduction. Such a parameter is known as a forwarding reference parameter. Forwarding reference parameters must be of the form T&&, where T is some deduced template parameter.
If you want to accept lvalues and rvalues and perfect-forward them, you should use the latter form. Although it might seem weird to you at first, this is a fairly common pattern.

Dependency injection in C++11 without raw pointers

I often use the "dependency injection" pattern in my projects. In C++ it is easiest to implement by passing around raw pointers, but now with C++11, everything in high-level code should be doable with smart pointers. But what is the best practice for this case? Performance is not critical, a clean and understandable code matters more to me now.
Let me show a simplified example. We have an algorithm that uses distance calculations inside. We want to be able to replace this calculation with different distance metrics (Euclidean, Manhattan, etc.). Our goal is to be able to say something like:
SomeAlgorithm algorithmWithEuclidean(new EuclideanDistanceCalculator());
SomeAlgorithm algorithmWithManhattan(new ManhattanDistanceCalculator());
but with smart pointers to avoid manual new and delete.
This is a possible implementation with raw pointers:
class DistanceCalculator {
public:
virtual double distance(Point p1, Point p2) = 0;
};
class EuclideanDistanceCalculator {
public:
virtual double distance(Point p1, Point p2) {
return sqrt(...);
}
};
class ManhattanDistanceCalculator {
public:
virtual double distance(Point p1, Point p2) {
return ...;
}
};
class SomeAlgorithm {
DistanceCalculator* distanceCalculator;
public:
SomeAlgorithm(DistanceCalculator* distanceCalculator_)
: distanceCalculator(distanceCalculator_) {}
double calculateComplicated() {
...
double dist = distanceCalculator->distance(p1, p2);
...
}
~SomeAlgorithm(){
delete distanceCalculator;
}
};
Let's assume that copying is not really an issue, and if we didn't need polymorphism we would just pass the DistanceCalculator to the constructor of SomeAlgorithm by value (copying). But since we need to be able to pass in different derived instances (without slicing), the parameter must be either a raw pointer, a reference or a smart pointer.
One solution that comes to mind is to pass it in by reference-to-const and encapsulate it in a std::unique_ptr<DistanceCalculator> member variable. Then the call would be:
SomeAlgorithm algorithmWithEuclidean(EuclideanDistance());
But this stack-allocated temporary object (rvalue-reference?) will be destructed after this line. So we'd need some copying to make it more like a pass-by-value. But since we don't know the runtime type, we cannot construct our copy easily.
We could also use a smart pointer as the constructor parameter. Since there is no issue with ownership (the DistanceCalculator will be owned by SomeAlgorithm) we should use std::unique_ptr. Should I really replace all of such constructor parameters with unique_ptr? it seems to reduce readability. Also the user of SomeAlgorithm must construct it in an awkward way:
SomeAlgorithm algorithmWithEuclidean(std::unique_ptr<DistanceCalculator>(new EuclideanDistance()));
Or should I use the new move semantics (&&, std::move) in some way?
It seems to be a pretty standard problem, there must be some succinct way to implement it.
If I wanted to do this, the first thing I'd do is kill your interface, and instead use this:
SomeAlgorithm(std::function<double(Point,Point)> distanceCalculator_)
type erased invocation object.
I could do a drop-in replacement using your EuclideanDistanceCalculator like this:
std::function<double(Point,Point)> UseEuclidean() {
auto obj = std::make_shared<EuclideanDistance>();
return [obj](Point a, Point b)->double {
return obj->distance( a, b );
};
}
SomeAlgorithm foo( UseEuclidean() );
but as distance calculators rarely require state, we could do away with the object.
With C++1y support, this shortens to:
std::function<double(Point,Point>> UseEuclidean() {
return [obj = std::make_shared<EuclideanDistance>()](Point a, Point b)->double {
return obj->distance( a, b );
};
}
which as it no longer requires a local variable, can be used inline:
SomeAlgorithm foo( [obj = std::make_shared<EuclideanDistance>()](Point a, Point b)->double {
return obj->distance( a, b );
} );
but again, the EuclideanDistance doesn't have any real state, so instead we can just
std::function<double(Point,Point>> EuclideanDistance() {
return [](Point a, Point b)->double {
return sqrt( (b.x-a.x)*(b.x-a.x) + (b.y-a.y)*(b.y*a.y) );
};
}
If we really don't need movement but we do need state, we can write a unique_function< R(Args...) > type that does not support non-move based assignment, and store one of those instead.
The core of this is that the interface DistanceCalculator is noise. The name of the variable is usually enough. std::function< double(Point,Point) > m_DistanceCalculator is clear in what it does. The creator of the type-erasure object std::function handles any lifetime management issues, we just store the function object by value.
If your actual dependency injection is more complicated (say multiple different related callbacks), using an interface isn't bad. If you want to avoid copy requirements, I'd go with this:
struct InterfaceForDependencyStuff {
virtual void method1() = 0;
virtual void method2() = 0;
virtual int method3( double, char ) = 0;
virtual ~InterfaceForDependencyStuff() {}; // optional if you want to do more work later, but probably worth it
};
then, write up your own make_unique<T>(Args&&...) (a std one is coming in C++1y), and use it like this:
Interface:
SomeAlgorithm(std::unique_ptr<InterfaceForDependencyStuff> pDependencyStuff)
Use:
SomeAlgorithm foo(std::make_unique<ImplementationForDependencyStuff>( blah blah blah ));
If you don't want virtual ~InterfaceForDependencyStuff() and want to use unique_ptr, you have to use a unique_ptr that stores its deleter (by passing in a stateful deleter).
On the other hand, if std::shared_ptr already comes with a make_shared, and it stores its deleter statefully by default. So if you go with shared_ptr storage of your interface, you get:
SomeAlgorithm(std::shared_ptr<InterfaceForDependencyStuff> pDependencyStuff)
and
SomeAlgorithm foo(std::make_shared<ImplementationForDependencyStuff>( blah blah blah ));
and make_shared will store a pointer-to-function that deletes ImplementationForDependencyStuff that will not be lost when you convert it to a std::shared_ptr<InterfaceForDependencyStuff>, so you can safely lack a virtual destructor in InterfaceForDependencyStuff. I personally would not bother, and leave virtual ~InterfaceForDependencyStuff there.
In most cases you don't want or need ownership transfer, it makes code harder to understand and less flexible (moved-from objects can't be reused). The typical case would be to keep ownership with the caller:
class SomeAlgorithm {
DistanceCalculator* distanceCalculator;
public:
explicit SomeAlgorithm(DistanceCalculator* distanceCalculator_)
: distanceCalculator(distanceCalculator_) {
if (distanceCalculator == nullptr) { abort(); }
}
double calculateComplicated() {
...
double dist = distanceCalculator->distance(p1, p2);
...
}
// Default special members are fine.
};
int main() {
EuclideanDistanceCalculator distanceCalculator;
SomeAlgorithm algorithm(&distanceCalculator);
algorithm.calculateComplicated();
}
Raw pointers are fine to express non-ownership. If you prefer you can use a reference in the constructor argument, it makes no real difference. However, don't use a reference as data member, it makes the class unnecessarily unassignable.
The down side of just using any pointer (smart or raw), or even an ordinary C++ reference, is that they allow calling non-const methods from a const context.
For stateless classes with a single method that is a non-issue, and std::function is a good alternative, but for the general case of classes with state or multiple methods I propose a wrapper similar but not identical to std::reference_wrapper (which lacks the const safe accessor).
template<typename T>
struct NonOwningRef{
NonOwningRef() = delete;
NonOwningRef(T& other) noexcept : ptr(std::addressof(other)) { };
NonOwningRef(const NonOwningRef& other) noexcept = default;
const T& value() const noexcept{ return *ptr; };
T& value() noexcept{ return *ptr; };
private:
T* ptr;
};
usage:
class SomeAlgorithm {
NonOwningRef<DistanceCalculator> distanceCalculator;
public:
SomeAlgorithm(DistanceCalculator& distanceCalculator_)
: distanceCalculator(distanceCalculator_) {}
double calculateComplicated() {
double dist = distanceCalculator.value().distance(p1, p2);
return dist;
}
};
Replace T* with unique_ptr or shared_ptr to get owning versions. In this case, also add move construction, and construction from any unique_ptr<T2> or shared_ptr<T2> ).

Overloaded "operator new" wants to see the type it's allocating

This seems like it ought to be obvious, but I'm blanking on it. I have
class SimpleMemoryPool {
char buffer[10000];
size_t idx;
void *Alloc(size_t nbytes) { idx += nbytes; return &buffer[idx - nbytes]; }
};
inline void* operator new (size_t size, SimpleMemoryPool& pool)
{
return pool.Alloc(size);
}
inline void* operator new[] (size_t size, SimpleMemoryPool& pool)
{
return pool.Alloc(size);
}
The idea is that I can allocate new objects out of my SimpleMemoryPool and then they'll all be "released" when the SimpleMemoryPool is destroyed:
void foo()
{
SimpleMemoryPool pool;
int *arr = new (pool) int[10];
double *arr2 = new (pool) double(3.14);
...do things with arr and arr2...
return; // and arr, arr2 are "released" at this point
}
One nitpick I've simplified away: The above code is sketchy because the double won't be 8-byte-aligned. Don't worry about that; my real SimpleMemoryPool code returns maxaligned chunks.
Here's the next thing you're probably thinking at this point: "Who calls the destructors?!" I.e., if I accidentally write
std::string *arr3 = new (pool) std::string;
then I'm in a world of hurt, because the compiler will generate a call to std::string::string() for me, but nobody will ever call std::string::~string(). Memory leaks, bad stuff follows.
This is the problem I want to solve. What I want to do is basically
class SimpleMemoryPool {
...
// (std::enable_if omitted for brevity)
template<typename T, typename... Args>
T *New(Args... args) {
static_assert(std::is_trivially_destructible<T>::value, "T must be trivially destructible!");
void *ptr = this->Alloc(nelem * sizeof (T));
return new (ptr) T(std::forward<Args>(args)...);
}
template<typename ArrayT>
auto NewArray(size_t nelem) -> std::remove_extent<ArrayT>::type {
typedef typename std::remove_extent<ArrayT>::type T;
static_assert(std::is_trivially_destructible<T>::value, "T must be trivially destructible!");
void *ptr = this->Alloc(nelem * sizeof (T));
return new (ptr) T[ nelem ];
}
};
...
int *arr = pool.NewArray<int>(10);
double *arr2 = pool.New<double>(3.14);
std::string *arr3 = pool.New<string>(); // fails the static_assert, hooray!
The problem with this approach is that it's ugly. It looks bad, and it invites later maintainers to come along and "fix" the code by adding a "proper" operator new, at which point we lose the safety of the static_assert.
Is there any way to get the best of both worlds — type-safety via the static_assert, and also a nice syntax?
You may assume C++11. I also welcome C++14 answers, even though they won't be immediately useful to me.
Adding a member operator new to all my classes (in this example int and double) is not acceptable. Whatever I do has to work out-of-the-box without changing a million lines of code.
This is probably a duplicate of Get type of object being allocated in operator new but I'd still like answers tailored to this particular use-case. There might be some nice idiom of which I'm not aware.

Function taking lambda expression

For practicing purposes I wanted to create a function similar to std::transform():
template<class Tin, class Tout>
std::vector<Tout> map( const std::vector<Tin>& in,
const std::function<Tout(const Tin&)>& mapper ) {
std::vector<Tout> ret;
for( auto elem : in ) {
ret.push_back( mapper( in ) );
}
return ret;
}
and I intended it to use it as follows:
std::vector<Bar> bars /* = ... */;
std::vector<Foo> foos = map( bars, []( const Bar& bar ) { return bar.to_foo(); } );
However, I get undefined references for the function call. What is the correct signature for my map() function?
*Update: * Here's the actual error message (Bar = std::string, Foo = IPv6 (own class))
config.cc:98:61: error: no matching function for call to ‘map(const std::vector<IPv6>&, InterfaceConfig::set_ip6(const std::vector<IPv6>&)::<lambda(const IPv6&)>)’
config.cc:98:61: note: candidate is:
utils.h:38:31: note: template<class Tin, class Tout> std::vector<Tout> utils::map(const std::vector<Tin>&, const std::function<Tout(const Tin&)>&)
And here's the call:
std::vector strings = utils::map( ips,
[]( const IPv6& ip ) { return ip.to_string(); } );
There is two things in your code that will not work.
First, when passing a lambda function as argument, I suggest using Template. The standard library on Microsoft seems to use this method for std::for_each for example.
And :
When function template has a return type, which cannot be deduced from arguments, or when function template doesn't have any argument, the type cannot be deduced by the compiler. This function will require template type argument specification.
Take a look at this example :
template<class Tout, class Tin, class Fun>
// ^^^^^^^^^^^
// Note that I changed the order of the types
std::vector<Tout> map( const std::vector<Tin>& in,
Fun mapper ) {
// ^^^^^^^^^^
std::vector<Tout> ret;
for( auto elem : in ) {
ret.push_back( mapper( elem ) );
}
return ret;
}
int main()
{
std::vector<int> bars /* = ... */;
std::vector<float> foos = map<float>( bars, []( int ) { return 1.0f; } );
// ^^^^^^^ Specify the type Tout
system( "pause" );
return 0;
}
EDIT :
Like it is said in the comment, we can use decltype and std::decay to not have to explicitly specify the result of the function :
template<class Tin, class Fun> // no Tout
// ^^^^^^^^^^^
auto map( const std::vector<Tin>& in, Fun mapper )
//^^^^ ^^^^^^^^^^
-> std::vector<typename std::decay< decltype( mapper( in.front() ) )>::type > {
std::vector<typename std::decay< decltype( mapper( in.front() ) )>::type > ret;
for( auto elem : in ) {
ret.push_back( mapper( elem ) );
}
return ret;
}
int main()
{
std::vector<int> bars /* = ... */;
std::vector<float> foos = map( bars, []( int ) { return 1.0f; } );
// No specification
system( "pause" );
return 0;
}
Let's explain a little bit.
First we will use the late-specified return type syntax. It will allow us to use the parameter names in the return type specification. We start the line with auto and put the return type specification after the parameters using ->.
We will use decltype because the decltype type specifier yields the type of a specified expression. It will be very useful in our case. For example to get the type of the function we passed in parameters, it is just decltype( f( someArg ) ).
Let's state what do we want : The return type of the function should be a vector of the return type of the function passed in argument right ? So we can return std::vector< decltype( mapper( in.front() ) )> and that's it ! (Why the in.front() ? We have to pass a parameter to the function to have a valid expression.)
But here again, we have a problem : std::vector does not allow references. To be certain that it will not be a problem for us, we will use the std::decay meta-function who applies lvalue-to-rvalue, array-to-pointer, and function-to-pointer implicit conversions to the type T, removes cv-qualifiers, remove references, and defines the resulting type as the member typedef type.. That is, if the function returns something like const Foo& it will end in Foo.
The result of all of that : std::vector< typename std::decay< decltype( mapper( in.front() ) )>::type >.
You have to repeat this expression again at the beginning of the function to declare the variable you will return.
Some usefull references about that :
http://en.cppreference.com/w/cpp/types/decay
http://en.wikipedia.org/wiki/Decltype
http://www.cprogramming.com/c++11/c++11-auto-decltype-return-value-after-function.html
http://msdn.microsoft.com/en-us/library/dd537655.aspx
It is not easy to explain, I hope my explanations are understandable.
There's no need to explicitly specify the result of map, it can be deduced. I'm also going to accept any range (something that provides begin and end), simply because doing so is trivial. I could make it even more generic and use the free begin and end versions, but that makes it even more complicated, so I won't.
template <typename Range, typename Func>
auto map(const Range& r, Func f)
-> std::vector<typename std::decay<decltype(f(*r.begin()))>::type> {
std::vector<typename std::decay<decltype(f(*r.begin()))>::type> result;
for (const auto& e : r) {
result.push_back(f(e));
}
// Alternatively:
//std::transform(r.begin(), r.end(), std::back_inserter(result), f);
return result;
}
This isn't exactly trivial code, so let me explain.
First, I use the late-specified return type syntax here: I start the function with auto and put the actual return type after the parameters, indicated with ->. This allows me to use parameter names in the return type specification, which is very useful in the decltype stuff I'm doing next.
So what do we actually want? We want a vector of whatever f returns when called with elements of r. What is that? Well, we can use decltype to find out. decltype(expr) gives you the type of expr. In this case, the expression is a call to f: decltype(f(arguments)). We have one argument: an element of the range. The only things a range gives us are begin() and end(), so let's use that: dereference begin() to get the actual value. The expression is now decltype(f(*r.begin())). Note that this is never actually evaluated, so it doesn't matter if the range is empty.
Ok, this gives us the return type of the function. But if we write std::vector<decltype(...)> that leaves us with a problem: the return type of the function could be a reference, but a vector of references is not valid. So we apply the std::decay metafunction to the return type, which removes references and cv-qualifiers on the referenced type, so if the function returns const Foo&, the result of std::decay is just Foo.
This leaves me with the final return type std::vector<typename std::decay<decltype(f(*r.begin()))>::type>.
And then you get to repeat the same thing to declare the actual variable holding the return value. Unfortunately, because there's no way to put type aliases at any reasonable point, you can't get rid of this.
Anyway, there was another problem with your original code, and that was declaring the loop variable as auto. If you call this map with a vector<Bar>, you end up with the loop
for (Bar b : in) { ... }
Notice how your loop variable is a value? This means that you copy every element of in to a local variable. If a Bar is expensive to copy, this is a serious performance issue. And if your transformation relies on the object identity of its argument (e.g. you return a pointer to a member), then your performance issue has become a correctness issue, because the resulting vector is full of dangling pointers. This is why you should use const auto& in the loop, or just use the std::transform algorithm internally, which gets this right.

Resources