Search code examples
c++stliteratoriterator-range

Pass a single parameter to a function that expects an iterator range


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?


Solution

  • 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);
    }