There are several possible improvements to your approach.

First, you can omit the second template parameter by making use of `decltype(*std::declval<Iterator>())`
What does this mean? So, the std::declval<Iterator>() fakes the construction of an Object of type Iterator. The star before derefences this iterator, which in turn gives us the stored value and the `decltype` gives us the respective type to this stored value.

Second, you can avoid most of the comparisons changing how your search works.
Instead, as already proposed by others, you can write a *lower_bound*-Function, that gives you the iterator next to val, that is, `v<=*it` and for every iterator right from it we have `v<*it` and changing the meaning of the parameter `end`: this iterator should not be part of the range, resulting in a left-closed-right-open implementation.

Put together a possible implementation could look like the following.
I did not test it, but the idea should be clear in case of any misspellings:

```cpp
template<typename Iterator, typename T>
Iterator binarySearch(Iterator begin, Iterator end, const  std::decay_t<decltype(*std::declval<Iterator>())>& v {
        auto diff = end - begin;
        while (diff > 1)
        {
           auto mid = low + diff / 2;
           if (v < *mid)
               end = mid;
           else // v >= *mid
               begin = mid;
           diff = end - begin;
        }
        if (begin == end || *begin < v)
           return end;
        return begin;
}
```

One could further improve this by making use of right-shift operations, and omitting the setting of the end-iterator in the loop.