【问题标题】:Pointer arithmetic with array_view使用 array_view 的指针算法
【发布时间】:2015-10-22 07:45:38
【问题描述】:

我刚刚看到 Herb Sutter 的“Writing Good C++14... 默认情况下”(https://www.youtube.com/watch?v=hEx5DNLWGgA) 的第一部分,并且我有一个关于 array_view 的(可能是愚蠢的)问题。

为了避免指针运算,本例是发送 array_view 而不是指针和长度,但是 array_view 如何处理这样的情况:

int vec[10];
func(vec+2, 5); //start from the 2nd element and process 5 of them

array_view 是否支持这种东西,或者我只是弄错了用例?

【问题讨论】:

    标签: c++ c++14 array-view


    【解决方案1】:

    首先,你可以从cppcon's Github repo获取the slides

    正如您在#8#10 中看到的,您可以编写以下内容:

    Run It Online !

    // http://llvm.org/apt/
    // sudo apt-get install clang-3.6 lldb-3.6 libc++-dev libc++abi-dev
    // clang-3.6 -stdlib=libc++ -std=c++14 main.cpp -lc++ -lc++abi
    
    #include <array>
    #include <vector>
    #include "array_view.h"  // https://github.com/Microsoft/GSL
    
    void func(gsl::array_view<int> av)
    {
        // ...
    }
    
    int main()
    {
        {
            int vec[10];
            func(vec);
            //func(vec, 5);    // syntax error (func expects exactly 1 argument)
            func({vec, 5});    // notice the curly braces
            func({vec+2, 5});
        }
    
        {
            std::vector<int> vec;
            func(vec);
        }
    
        {
            size_t len = 10;
            int* p = new int[10];
            func({p,len});
            // remember to delete[] p
        }
    
        {
            std::array<int, 2> arr;
            func(arr);
        }
    }
    

    这是有道理的。如果您查看array_view.h,您会看到array_view 的所有构造函数:

    constexpr array_view(pointer ptr, bounds_type bounds)
    constexpr array_view(T * const & data, size_type size)
    constexpr array_view(T(&arr)[N], size_type size)
    constexpr array_view (const std::array<std::remove_const_t<value_type>, N> & arr)
    // ...
    

    【讨论】:

    • 感谢您的回购,我不知道!正如我之前告诉@Drax 的,我现在看到func({vec+2, 5}) 是最好的方法,但我仍然认为在array_view 中有一个偏移参数会很好,所以我们可以以更安全的方式构造它。如果数组有 3 个元素并且我执行 func({vec+4, 5}),我猜它仍然是运行时错误,但如果调用类似于 func({vec, 4, 5}),则可能是编译时错误。
    • 无需猜测,您可以在线测试;)(参见“在线运行!”按钮)
    【解决方案2】:

    使用string_view,您可以这样做:

    const char* str = "hello world!"; 
    func(std::experimental::string_view(str + 2, 5));
    

    即使用视图的构造函数之一从子字符串构建它。

    因此,使用array_view,您可能能够做到这一点:

    int vec[10];
    func(std::experimental::array_view(vec + 2, 5));
    

    注意:c++14 好像还没有官方的array_view

    【讨论】:

    • 这不是违背 array_view 的全部目的吗?据我了解,使用它是因为如果我们越过数组的边界,它会通过给出编译错误来更安全。像这样使用它(array_view(vec + 2, 5)),我们可以在构造array_view之前越过数组的边界。
    • @Andrei 在array_view 构建之前,您不会获得好处。在您构建array_view 时,您有一个数组,因此您可以处理数组的优缺点。在 func 内部时,尽管您对数组有一个更安全的抽象视图。
    • 我猜你是对的。在array_view 中有一个offset 参数会很好,所以我们可以以安全的方式构造它。
    猜你喜欢
    • 1970-01-01
    • 2011-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-27
    • 1970-01-01
    相关资源
    最近更新 更多