简体   繁体   中英

c++ loop through a class private unique_ptr array from non-friend external utility function without using c-style for loop

I've got a class with:

class vector_class {
private:
    std::unique_ptr<int[]> my_vector;
    int size_;

public:
    auto at(int) const -> int; // returns value at subscript
    auto at(int) -> int&;
    auto size() -> int; // returns vector size
}

I've been asked to construct an external function that takes 2 of these objects and returns the inner_product. Problem is that I have the following restrictions:

  1. Can't add any public functions.
  2. Shouldn't use friendship
  3. Shouldn't use c-style for loops (ie should use algorithms).
  4. Can't use any stl containers.

I can't use for_each because I don't have an iterator (since the vector is private non-friend). I can't do for (i = 0; i < a.size(); ++i) ... (since no basic for loop).

I guess I could write a custom iterator class but this is a lot of work and wondering if I've missed an easier solution... Any suggestions?

Iterators were designed to emulate much of the behavior of pointers, so much that all pointers can be used as iterators.

So if you have an array, and the number of elements in the array, you can use a pointer to the first element of the array as the begin iterator. And a pointer to one element beyond the last element (ie begin + size ) as the end iterator. Then you can use these "iterators" with any normal standard function expecting an iterator pair.

For your specific case, &my_vector[0] as begin, and &my_vector[size_] as end.

Now, due to the limitations and requirements of your exercise, the simplest solution is probably to get these pointers through the public at() function. Or if the class has an overloaded operator[] you can use that instead:

inner_product(&i[0], &i[i.size()], &j[0]);

Because there are two overloads of the at function (and probably of the [] operator if it exists) we might need to specifically ask for the overload that returns a reference, if the compiler doesn't select the correct overloads to begin with.

This can be done by defining our own temporary reference variables:

auto const& first_begin  = i[0];
auto const& first_end    = i[i.size()];
auto const& second_begin = j[0];

auto result = inner_product(&first_begin, &first_end, &second_begin, 0);

Or, since it seems that the at function have a proper reference-returning overload, you can use that instead of [] :

auto result = inner_product(&i.at(0), &i.at(i.size()), &j.at(0), 0);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM