Consider the following function:
using iteratorPair = std::pair<std::set<Record>::const_iterator, std::set<Record>::const_iterator>;
using iteratorList = std::vector<iteratorPair>;
template<class FunctionPtr>
iteratorList splitByParameter(iteratorPair& range, const FunctionPtr& accesorFunction)
{
iteratorList list;
list.push_back(range);
auto firstValueFunction = std::bind(accesorFunction, *range.first);
auto value = firstValueFunction();
for (auto iterator = range.first; iterator != range.second; ++iterator)
{
auto iteratorValueFunction = std::bind(accesorFunction, *iterator);
if (iteratorValueFunction() != value)
{
value = iteratorValueFunction();
list.back().second = iterator;
list.emplace_back(iterator, range.second);
}
}
return list;
}
It's purpose is to create iterator ranges for records in a std::set
that have a common value... e.g. all the green eyed people, and then can be called again on those subsets for get additional ranges, e.g. all the green eyed males. You pass it a range to operate on, and a function pointer to the accessor that returns the value you want to compare.
I built this with MSVC 2019 16.4.3, and was surprised that I could pass accessorFunction
pointers that had different return types, so that in one invocation of the function, value
might be an enum class
, and in the next invocation it could be a double
. I'm using various strong types (units), that are not implicitly convertible to each other.
That would make sense to me if value
was a template type, but I didn't think auto
could be used in that fashion? Is this just some UB or a compiler quirk, or is it actually legal to use auto
this way?