2

为了设置iterator_type与关联的迭代器类型,我必须为 YYY、ZZZ 写什么T?如果可能,它应该在 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

4 回答 4

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;
};
于 2012-11-26T17:51:13.080 回答
4

我的解决方案是:

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

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

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

  • std::declval<T>()返回一个右值引用 ( T&&)。
  • std::begin通过非常量引用获取其参数。
  • 非常量引用不能绑定到临时对象。

std::declval<T&>但是由于引用折叠而返回左值引用。

于 2017-06-20T19:58:43.327 回答
3

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

typedef typename std::remove_reference<
                    decltype ( 
                        begin ( std::declval<T> () )
                    )
                 >::type
        type;
于 2012-11-26T17:35:55.553 回答
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;
}
于 2012-11-26T20:22:16.617 回答