为了将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
对应的迭代器类型。对于数组,相应的迭代器将是一个指针,对于一个字符串,它是任何字符串定义为其迭代器类型。
答案 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::begin
在T
实例上调用时返回的类型。声明std::declval<T&>
返回T&
,我们可以在其上调用std::begin
。
这与JohnB的答案不同,我们将对容器类型的引用传递给std::begin
。这是必要的,因为:
std::declval<T>()
返回右值引用(T&&
)。std::begin
通过非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;
}