Consider a function that accepts one or more parameters (e.g. file names). In order to make it versatile, it is advantageous to write it for a general iterator range:
template<class Iter> void function(Iter first, Iter last) { // do something }
Now we can invoke it in the following way, independently of how we store the arguments:
WhateverContainer container; function(std::begin(container), std::end(container));
For example, the STL relies heavily on this paradigm.
Now, imagine we want to invoke the function with a single argument that is not stored in a container. Of course we can write:
const int value = 5; std::vector<int> vec(1, value); function(std::begin(vec), std::end(vec));
But this solution seems clumsy and wasteful to me.
Question: Is there a better low-overhead way of creating an iterator-range-compatible representation of a single variable?
You can use pointers, for once:
function(&value, &value + 1);
In generic code, std::addressof
instead of the unary operator &
is somewhat safer, depending on your level of paranoia.
You can of course wrap this in an overload for easier use:
template <class T> decltype(auto) function (T &&e) { auto p = std::addressof(e); return function(p, p + 1); }
You can treat it like an array of one element per [expr.unary.op]/3:
function(&value, &value + 1);
For purposes of pointer arithmetic ([expr.add]) and comparison ([expr.rel], [expr.eq]), an object that is not an array element whose address is taken in this way is considered to belong to an array with one element of type T.
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