我想在C ++数组中使用迭代器,但也使用原始指针。 我可以使用静态向量:
#define SIZE 10
int vect[SIZE] = {0};
vect[3] = 5;
int* p = std::find(std::begin(vect), std::end(vect), 5);
bool success = p != std::end(vect);
如何使用原始指针(可能是堆分配的向量)来实现? 当然编译器不知道数据的大小,所以这段代码
int* pStart = vect;
std::find(std::begin(pStart), std::end(pStart), 5);
给出
error C2784: '_Ty *std::begin(_Ty (&)[_Size])' :
could not deduce template argument for '_Ty (&)[_Size]' from 'int *'
是否可以让begin()
和end()
了解它?
答案 0 :(得分:4)
是否可以让begin()和end()知道它?
可以为指针实现std::begin
,但是不可能实现std::end
(因为正如你所说,大小未知),所以它有点无意义
但是,您不需要其中任何一个使用std::find
:
int* p = std::find(pStart, pStart + SIZE, 5);
答案 1 :(得分:4)
不能在指针上使用std::begin
和std::end
。与大小是类型的一部分的数组不同,因此指针不能保持它指向的东西的大小。在您使用指针的情况下,您必须使用
std::find(pStart, pStart + SIZE, 5);
避免这种情况的方法是在你不知道编译时szie是什么时使用std::vector
。它将为您管理内存并提供begin
和end
成员函数。
答案 2 :(得分:2)
下面:
std::begin(pStart), std::end(pStart)
你试图抓住指针的开头和结尾。都能跟得上!
相反,你的意思是:
std::begin(vect), std::end(vect)
无论您使用数组,std::array
,std::vector
还是特别大的大象 - 来获取容器的边界,都需要容器。
答案 3 :(得分:0)
我想在C ++数组中使用迭代器,但也使用原始指针。
你倒退了。原始指针是迭代器。他们遍历数组。
您可以将它们用于std::begin
和std::end
所能完成的所有事情。最值得注意的是,您可以将它们传递给<algorithm>
中的C ++标准算法。
指针本身不能被迭代。迭代器不能被迭代。
int* pStart = vect; std::find(std::begin(pStart), std::end(pStart), 5);
非常宽松地说,指针只是一个数字。数字的“开始”和“结束”是什么?这段代码没有下列意义:
int i = 123;
std::find(std::begin(i), std::end(i), 5); // error
是否可以让
begin()
和end()
了解它?
指针可能指向某个数组的开头。但是这些知识必须与指针一起保存。您需要维护一个大小或结束指针以及一个开始指针,并将所有数据保存在一起。
这正是std::array
和std::vector
为你做的事情。
答案 4 :(得分:0)
当我处理裸数组时,我依靠简单的容器使它们与C ++对范围的一般处理兼容。
例如:
#include <iostream>
#include <memory> // for std::unique_ptr
#include <algorithm> // for std::reverse
#include <numeric> // for std::iota
template<typename T>
class range_view {
public:
range_view(T* data, std::size_t size)
: m_data { data },
m_size { size } { }
const T* begin() const { return m_data; }
const T* end() const { return m_data + m_size; }
T* begin() { return m_data; }
T* end() { return m_data + m_size; }
private:
T* m_data;
std::size_t m_size;
};
int main() {
// this is your actual data
auto pdata = std::make_unique<int>(20);
// this is a handle you use to work with your data
auto data_view = range_view<int>(pdata.get(), 20);
// for example, you can fill it with numbers 0, ... , N - 1
std::iota(data_view.begin(), data_view.end(), 0);
// it is now compatible with c++'s range-based operators
std::cout << "my data...\n";
for(auto && item : data_view) std::cout << item << " ";
std::reverse(data_view.begin(), data_view.end());
std::cout << "\nreversed...\n";
for(auto && item : data_view) std::cout << item << " ";
std::cout << "\n";
}
编译并运行
$ g++ example.cpp -std=c++14
$ ./a.out
my data...
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
reversed...
19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
您仍然需要担心将正确的维度传递给构造函数,如果基础指针被删除,它将会失败,但无论如何您都不得不担心。