Binary Search For Data Types With Relation Operators I am trying to write a binary search algorithm to work with any data type that is defined to work with the relational operators and returns the position of the found element. I want to know if there is anything I need to be aware of when dealing with user defined types. As well as any flaws or improvements that I can make. Also one other question is how does my search compare to the built in binary_search function?

#include &lt;iostream&gt;
#include &lt;iomanip&gt;
#include &lt;type_traits&gt;

template&lt;typename T, typename U&gt;
U BinarySearch(T *arr, T toFind, U _size){ //make return type same as size for overflow issues
    static_assert(std::is_integral&lt;U&gt;::value, "Integral type required for size of array");

    U mid, low = 0, high = _size-1; //maintain same integral types
    T m, l = arr[low], h = arr[high]; //maintain same T types

    while(l&lt;=toFind &amp;&amp; h&gt;=toFind){
        mid = (high + low)/2;
        m = arr[mid];
        if(m &gt; toFind){
            h = arr[high = mid - 1];
        }
        else if(m &lt; toFind){
            l = arr[low = mid + 1];
        }
        else
            return mid; //postion point + 1
    }

    //exits if not found
    return -1;
}

const auto SIZE = 10;

int main()
{
    double arr[SIZE] = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.1};
    auto pos = BinarySearch(arr, 1.1, SIZE);
    std::cout &lt;&lt; pos &lt;&lt; '\n';
    return 0;
}


Thanks for all your advice in advance.
Apart from the fact that you should prefer writing algorithms to work with iterators (to enable you to sort things that aren't arrays, such as std::lists), there are a few things here that are problematic:


Don't make assumptions about the signedness of your U type, which seems to represent the size type of the array. Oftentimes, U will be unsigned (e.g. because it is std::size_t), which means returning -1 on not finding a value might be unexpected behaviour for your users.
Check that _size is greater than zero. If it is not, your program invokes undefined behaviour. 
Take toFind by const reference since you don't know which type it will be, whether it will be trivially copyable and so on and so forth. The same is true for m, l and h; you should either make them pointers to elements in the array or make them store the index to their respective elements instead.
Be careful with overflow. In particular, (high + low)/2; may overflow the passed size type and you may end up getting nowhere. Instead, divide them separately and add the results together.




These are the pitfalls and dangers I spotted. There is a lot more to say about your code, however, but I will leave this to somebody else.