如何确定容器的迭代器类型?

时间:2012-11-26 17:15:56

标签: c++ typetraits

为了将iterator_type设置为与T关联的迭代器类型,我必须为YYY,ZZZ编写什么?如果可能的话,它应该在Visual Studio C ++ 2010中工作(但通用标准解决方案也可以)。

template<class T>
struct iterator_for {
    typedef YYY<T>::ZZZ type;
}

因此我想:

iterator_for<double[3]>::type is double *
iterator_for<std::string>::type is std::string::iterator
iterator_for<char[12]>::type is char *

我有一个模板化的包装类Wrapper<T>存储可迭代的东西(即容器或字符串或数组),我想定义一个返回指向包装对象的迭代器的函数。为此,我需要能够谈论与T对应的迭代器类型。对于数组,相应的迭代器将是一个指针,对于一个字符串,它是任何字符串定义为其迭代器类型。

4 个答案:

答案 0 :(得分:4)

如果您只想将容器与指针分开,可以试试这个

template<class T>
struct iterator_for 
{
    typedef typename T::iterator  type;
};

template<class T>
struct iterator_for<T*>
{
    typedef T*  type;
};

template<class T, std::size_t N>
struct iterator_for<T (&)[N]>
{
    typedef T*  type;
};

答案 1 :(得分:3)

好的,一种可能性是(在C ++ 11中,但在VS 2010中不起作用):

typedef typename std::remove_reference<
                    decltype ( 
                        begin ( std::declval<T> () )
                    )
                 >::type
        type;

答案 2 :(得分:2)

我的解决方案是:

typedef decltype(std::begin(std::declval<T&>())) type;

迭代器类型是std::beginT实例上调用时返回的类型。声明std::declval<T&>返回T&,我们可以在其上调用std::begin

这与JohnB的答案不同,我们将对容器类型的引用传递给std::begin。这是必要的,因为:

  • std::declval<T>()返回右值引用(T&&)。
  • std::begin通过非const引用获取其参数。
  • 非const引用无法绑定到临时引用。
然而,

std::declval<T&>因参考折叠而返回左值参考。

答案 3 :(得分:1)

Boost图书馆已经有了这个:

#include <boost/range.hpp>
#include <iostream>
#include <string>
#include <vector>

template <typename T> void print_list(const T& container) {
    typedef typename boost::range_iterator<const T>::type iter;
    for (iter i = boost::begin(container); i != boost::end(container); ++i)
        std::cout << *i << ";";
    std::cout << "\n";
}

int main() {
    double array[] = {1.0,2.0,3.0};
    std::string str = "Hello";
    std::vector<int> vec(3, 10);
    print_list(array);  // prints 1;2;3;
    print_list(str);    // prints H;e;l;l;o;
    print_list(vec);    // prints 10;10;10;
}