Can std::begin work with array parameters and if so, how?

后端 未结 5 2171
慢半拍i
慢半拍i 2020-12-03 02:08

I have trouble using std::begin() and std::end() (from the iterator library) with c-style array parameters.

void SetOr         


        
相关标签:
5条回答
  • 2020-12-03 02:21

    First off, note that the parameter declaration const double i_point[3] is absolutely equivalent to const double* i_point. That is, the function takes any pointer to double const independent of the number of elements pointed to. As a result, it doesn't know the size and std::begin() and std::end() can't deduce the size (well, std::begin() doesn't really need to deduce the size anyway).

    If you really want to use std::begin() and std::end() you need to pass an array with three element or a reference to such a beast. Since you cannot pass arrays by value, your best bet is to pass it by reference:

    void SetOrigin(double const (&i_point)[3]) {
        // ...
    }
    

    This function only accepts arrays with exactly three elements as arguments: You cannot pass a pointer to three doubles or a part of a bigger array. In return, you can now use std::begin() and std::end().

    0 讨论(0)
  • 2020-12-03 02:25

    While not directly answering your question (it has already been answered sufficiently by M M. and Dietmar Kühl), you appear to want to initialize some std::vector in this function. That said, why not just have:

    std::vector v;
    std::copy(std::begin(x), std::end(x), std::back_inserter(v));
    // or std::copy(x, x + 3, std::back_inserter(v));
    

    Instead of a function call to your function that is trying to do this?

    Alternatively, you could write you function like this:

    template<typename RandomIterator>
    void SetOrigin(RandomIterator start, RandomIterator end)
    {
        std::vector<int> v;
        std::copy(start, end, std::back_inserter(v));
        SetOrigin(v);
    }
    

    and then call it using:

    double xyz[3];
    SetOrigin(std::begin(xyz), std::end(xyz));
    
    0 讨论(0)
  • 2020-12-03 02:30
    void SetOrigin(const double i_point[3])
    

    is as same as

    void SetOrigin(const double i_point[])
    

    or

    void SetOrigin(const double *i_point)
    

    So, std::begin and std::end can not accept it. In C++ you can not pass an array but as a pointer or reference. If it's a pointer then it doesn't carry any information of passed array.

    Your alternatives are std::vector or std::array.

    0 讨论(0)
  • 2020-12-03 02:32

    Yes, std::begin and std::end can work with parameters that are C style arrays.

    The trick is in passing a parameter that's a C style array. When you specify a 1D array as a normal parameter to a normal function, its type is silently adjusted from "array of T" to "pointer to T". When you call that function, what gets passed isn't the array (as an array), but a pointer to the first element of the array.

    It is, however, possible to pass an array by reference to a function template:

    template <class T, size_t N>
    void function(T (&array)[N]) {
       // function body here
    }
    

    In this case, where you're passing an actual array (albeit, by reference) rather than a pointer, you can use std::begin and std::end perfectly well. For example:

    template <class T, size_t N>
    T sum(T (&array)[N]) { 
        return std::accumulate(std::begin(array), std::end(array), T());
    }
    

    Now passing an array is trivial, such as:

    int array[] = {1, 2, 3, 4};
    
    auto total = sum(array);
    

    std::begin and std::end themselves are implemented similarly to sum--the array is passed by reference, so they can look something like this:

    template <class T, size_t N>
    T *begin(T (&array)[N]) { 
        return array; 
    }
    
    template <class T, size_t N>
    T *end(T (&array)[N]) {
        return array + N;
    }
    

    Note that although these were added to the standard more recently, they don't require any particularly tricky use of templates, so the implementation above should work fine with a plain old C++98 compiler (and, if memory serves, even with pre-standard compilers such as VC++ 6).

    0 讨论(0)
  • 2020-12-03 02:33

    Have you looked at std::array?

    It works better with other STL components

    0 讨论(0)
提交回复
热议问题