如何检测类型是迭代器还是 const_iterator

发布于 2024-10-26 11:04:56 字数 303 浏览 2 评论 0原文

我想知道是否有一种方法可以在编译时检查某些迭代器类型的类型 T 是否是 const_iterator。迭代器和 const 迭代器定义的类型(value_type、指针等)是否存在差异?

我想实现这样的目标:

typedef std::vector<int> T;

is_const_iterator<T::iterator>::value       // is false
is_const_iterator<T::const_iterator>::value // is true

I'm wondering, if there is a way to check at compile time whether a type T of some iterator type is a const_iterator, or not. Is there some difference in the types that iterators define (value_type, pointer, ...) between iterators and const iterators?

I would like to achieve something like this:

typedef std::vector<int> T;

is_const_iterator<T::iterator>::value       // is false
is_const_iterator<T::const_iterator>::value // is true

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

捶死心动 2024-11-02 11:04:56

C++03 解决方案:

由于没有一个答案似乎正确,这是我使用 GCC 的尝试:

template<typename T>
struct is_const_pointer { static const bool value = false; };

template<typename T>
struct is_const_pointer<const T*> { static const bool value = true; };

template <typename TIterator>
struct is_const_iterator
{
    typedef typename std::iterator_traits<TIterator>::pointer pointer;
    static const bool value = is_const_pointer<pointer>::value;
};

示例:

int main()
{
    typedef std::vector<int>::iterator it_type;
    typedef std::vector<int>::const_iterator const_it_type;

    std::cout << (is_const_iterator<it_type>::value) << std::endl;
    std::cout << (is_const_iterator<const_it_type>::value) << std::endl;
}

输出:

0
1

在线演示:http:// /ideone.com/TFYcW

C++03 Solution:

As none of the answer seems correct, here is my attempt which is working with GCC:

template<typename T>
struct is_const_pointer { static const bool value = false; };

template<typename T>
struct is_const_pointer<const T*> { static const bool value = true; };

template <typename TIterator>
struct is_const_iterator
{
    typedef typename std::iterator_traits<TIterator>::pointer pointer;
    static const bool value = is_const_pointer<pointer>::value;
};

Example:

int main()
{
    typedef std::vector<int>::iterator it_type;
    typedef std::vector<int>::const_iterator const_it_type;

    std::cout << (is_const_iterator<it_type>::value) << std::endl;
    std::cout << (is_const_iterator<const_it_type>::value) << std::endl;
}

Output:

0
1

Online Demo : http://ideone.com/TFYcW

盛装女皇 2024-11-02 11:04:56

C++11

template<class IT, class T=decltype(*std::declval<IT>())>    
constexpr bool  
is_const_iterator() {   
        return  ! std::is_assignable <
                decltype( *std::declval<IT>() ),
                T   
        >::value;
}

C++11

template<class IT, class T=decltype(*std::declval<IT>())>    
constexpr bool  
is_const_iterator() {   
        return  ! std::is_assignable <
                decltype( *std::declval<IT>() ),
                T   
        >::value;
}
风柔一江水 2024-11-02 11:04:56

至少在 gcc 上有效的一种方法是通过 reference typedef:

struct true_type { };
struct false_type { };

template<typename T>
struct is_const_reference
{
    typedef false_type type;
};

template<typename T>
struct is_const_reference<T const &>
{
    typedef true_type type;
};

template<typename T>
struct is_const_iterator
{
    typedef typename is_const_reference<
        typename std::iterator_traits<T>::reference>::type type;
};

您可以通过使用来验证它是否有效。

inline bool test_internal(true_type)
{
    return true;
}

inline bool test_internal(false_type)
{
    return false;
}

template<typename T>
bool test(T const &)
{
    return test_internal(typename is_const_iterator<T>::type());
}

bool this_should_return_false(void)
{
    std::list<int> l;
    return test(l.begin());
}

bool this_should_return_true(void)
{
    std::list<int> const l;
    return test(l.begin());
}

如果优化级别足够高,最后两个函数应减少为 return false; 和分别返回 true;。至少他们对我来说是这样。

One method that works at least on gcc is via the reference typedef:

struct true_type { };
struct false_type { };

template<typename T>
struct is_const_reference
{
    typedef false_type type;
};

template<typename T>
struct is_const_reference<T const &>
{
    typedef true_type type;
};

template<typename T>
struct is_const_iterator
{
    typedef typename is_const_reference<
        typename std::iterator_traits<T>::reference>::type type;
};

You can verify that it works by using

inline bool test_internal(true_type)
{
    return true;
}

inline bool test_internal(false_type)
{
    return false;
}

template<typename T>
bool test(T const &)
{
    return test_internal(typename is_const_iterator<T>::type());
}

bool this_should_return_false(void)
{
    std::list<int> l;
    return test(l.begin());
}

bool this_should_return_true(void)
{
    std::list<int> const l;
    return test(l.begin());
}

With a sufficiently high optimization level, the last two functions should be reduced to return false; and return true;, respectively. At least they do for me.

爱的那么颓废 2024-11-02 11:04:56

在 C++11 中,新的标准头 提供了 std::is_const
所以 Nawaz 的解决方案可以简化:

template<typename Iterator>
struct is_const_iterator
{
    typedef typename std::iterator_traits<Iterator>::pointer pointer; 
    static const bool value = 
        std::is_const<typename std::remove_pointer<pointer>::type>::value;
};

With C++11, the new standard header <type_traits> provides std::is_const<T>,
so Nawaz's solution can be simplified:

template<typename Iterator>
struct is_const_iterator
{
    typedef typename std::iterator_traits<Iterator>::pointer pointer; 
    static const bool value = 
        std::is_const<typename std::remove_pointer<pointer>::type>::value;
};
仲春光 2024-11-02 11:04:56

这有点 hacky,因为您必须传递 T 本身,但它可以工作(模板专业化,g++ 4.4.5):

template<typename T, typename S>
struct is_const_iterator {
    enum {
        value = false
    };
};

template<typename T>
struct is_const_iterator<T, typename T::const_iterator> {
    enum {
        value = true
    };
};

像这样使用:

typedef std::vector<int> T;
is_const_iterator<T, T::iterator>::value           //is false
is_const_iterator<T, T::const_iterator>::value     //is true

This is a bit hacky because you have to pass T itself but it works (template specialization, g++ 4.4.5):

template<typename T, typename S>
struct is_const_iterator {
    enum {
        value = false
    };
};

template<typename T>
struct is_const_iterator<T, typename T::const_iterator> {
    enum {
        value = true
    };
};

Use like this:

typedef std::vector<int> T;
is_const_iterator<T, T::iterator>::value           //is false
is_const_iterator<T, T::const_iterator>::value     //is true
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文