Why is a vector of pointers not castable to a const vector of const pointers?

后端 未结 4 2045
梦谈多话
梦谈多话 2021-01-03 22:17

The type vector is not convertible to const vector. For example, the following gives a compilation error:

4条回答
  •  一整个雨季
    2021-01-03 22:57

    void fn(const vector)
    

    As the top-level const qualifier is dropped for the function type, this is (at the call site) equivalent to:

    void fn(vector)
    

    Both of which request a copy of the passed vector, because Standard Library containers follow value semantics.

    You can either:

    • call it via fn({vc.begin(), vc.end()}), requesting an explicit conversion
    • change the signature to, e.g. void fn(vector const&), i.e. taking a reference

    If you can modify the signature of fn, you can follow GManNickG's advice and use iterators / a range instead:

    #include 
    template
    void fn(ConstRaIt begin, ConstRaIt end)
    {
        for(; begin != end; ++begin)
        {
            std::cout << *begin << std::endl;
        }
    }
    
    #include 
    int main()
    {
        char arr[] = "hello world";
        std::vector vc;
        for(char& c : arr) vc.push_back(&c);
    
        fn(begin(vc), end(vc));
    }
    

    This gives the beautiful output

    hello world
    ello world
    llo world
    lo world
    o world
     world
    world
    orld
    rld
    ld
    d

    The fundamental issue is to pass around Standard Library containers. If you only need constant access to the data, you don't need to know the actual container type and can use the template instead. This removes the coupling of fn to the type of container the caller uses.

    As you have noticed, it's a bad idea to allow access of a std::vector through a std::vector&. But if you don't need to modify the container, you can use a range instead.

    If the function fn shall not or cannot be a template, you could still pass around ranges of const char* instead of vectors of const char. This will work with any container that guarantees contiguous storage, such as raw arrays, std::arrays, std::vectors and std::strings.

提交回复
热议问题