How to restrict template parameter to pointer or random access iterator only?

天涯浪子 提交于 2020-01-11 09:26:10

问题


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.


回答1:


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");


来源:https://stackoverflow.com/questions/23665053/how-to-restrict-template-parameter-to-pointer-or-random-access-iterator-only

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!