Question

Is there a way to restrict the parameter type of a template function to only pointers or random-access iterators?

Say I am developing a sorting function which works only with random accessible containers. I am looking for a way to throw a compile-time error if the user passes a non-random-access iterator.

#include <type_traits>
#include <iterator>

template <class Iterator> void mySort(Iterator begin, Iterator end){

    /*The below condition must be true if the 'Iterator' type is a pointer 
    or if it is of Category random_access_iterator_tag. How to make such check?*/
    static_assert(some condition, "The mySort() function only accepts random access iterators or raw pointers to an array.\n");

    for (Iterator it = begin; it != end; ++it){
        /*Some kind of sorting is performed here, which 
        uses arithmetic operators + and - in the iterator type. */
    }
}

I know that to check if a type is a pointer I could use std::is_pointer<Iterator>::value and to check if the iterator is random access I could use std::is_same<std::random_access_iterator_tag, Iterator::iterator_category>::value.

The first problem is that both checks should be OR'd inside the same static_assert(), otherwise if either one was matched, the other would not.

The second problem is that the random access check would fail if the function was to be called called in such a way: mySort<int*>(...). This obviously happens since int* does not have the ::iterator_category definition.

Does anybody have an idea how to solve this? I also know the compiler would automatically throw errors for the attempt of using arithmetic operators with non-random-access iterators, but I would like to display a more comprehensive error message through static_assert().

As a follow up question. In the case 'Iterator' is a pointer type, is there a way to assert it is of a primitive type (non struct/class)?

Thank you in advance.

Was it helpful?

Solution

Use iterator traits:

static_assert(
    std::is_same<std::random_access_iterator_tag,
                 typename std::iterator_traits<Iterator>::iterator_category>::value,
    "The mySort() function only accepts random access iterators or raw pointers to an array.\n");
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top