如何将std :: vector名称视为C类型的数组名称?

时间:2017-02-02 11:17:38

标签: c++ arrays vector

在C中,很容易做到这样的事情:

int foo (int arr[], int size) {

    // Do some stuff.

    // Recur ignoring half of the input array.
    return foo (arr + size / 2, size / 2);
}

我知道我们能够做到这一点,因为在C中,数组的名称基本上是指向内存中连续块的指针,基本指针算法可以正常工作。

我的问题是如何使用C ++ vector或array容器实现这种便利?从根本上说,还有其他可行的方法吗?

据我所知,这根本不起作用:

int foo (vector<int>& arr, int size) {

    // Do some stuff.

    // Recur ignoring half of the input array.
    return foo (arr + size / 2, size / 2);
}

3 个答案:

答案 0 :(得分:1)

C ++解决方案是根据您使用的对象进行思考。一个vector

因此,您可以简单地使用迭代器并执行以下操作:

arr.begin()
arr.begin()+(size/2)

换句话说:不是将C概念推到C ++上,而是使用相应的C ++概念。

在这种情况下,您可以使用iterators制作&#34;部分&#34;您的阵列&#34;可用&#34;对外界来说。

答案 1 :(得分:1)

如果您无法更改功能签名,则可以传递与该功能兼容的向量data()size()属性:

foo(v.data(), v.size());

答案 2 :(得分:0)

由于您正在使用std::vector<int>,明显的答案是根本不更改功能。

简单地称呼它。

 foo(&some_vector[0], some_vector.size());    // assume some_vector is not const

这会将指向第一个元素的指针和some_vector的大小传递给您的C风格foo()。由于std::vector的元素保证是连续的,因此可以按照您的要求运行。

然而,就个人而言,我不会这样做。我使用迭代器

 #include <iterator>

 int foo (std::vector<int>::iterator begin, std::vector<int>::iterator end)
 {

     // Do some stuff.

     // Recur ignoring half of the input array.

    std::advance(begin, std::distance(begin, end)/2);
    return foo (begin, end);
 }

 //  to call it

 foo(some_vector.begin(), some_vector.end());

你显然需要一些逻辑来避免函数中的无限递归。但是你开始使用的功能也是如此。

模板允许我更简单和更通用,因为没有必要对迭代器(或它们来自哪种类型的容器)进行硬编码

 #include <iterator>

 template<class Iterator>
 int foo (Iterator begin, Iterator end)
 {

     // Do some stuff.

     // Recur ignoring half of the input array.

    std::advance(begin, std::distance(begin, end)/2);
    return foo (begin, end);
 }

 // call like before

std::advance()std::distance()的要求非常小 - 基本上迭代器是标准调用输入迭代器(这意味着它们可以用于顺序输入)操作,其中迭代器指向的每个值只读一次,然后迭代器递增)。你的&#34;做一些事情&#34;代码可能会引入更多限制性要求。