What is the best way to return a reference to an array of pointers with a constant size?

I have an array of pointers declared as a member of a class as follows:

class Bar { private: static constexpr int SIZE = 10; Foo* m[SIZE]; } 

In one of my class methods, I would like to return a pointer (or, preferably, a link) to this array. The array has a known size at compile time, but I keep track of how many items I placed there (this is buffer material).

What is the best way to return a reference to this array in C ++ 11?

Here is what I tried:

 GetArray(Foo* &f[], unsigned &size) const 

I like the syntax because it makes it clear that the reference value is an array of pointers, but it gives a compiler error: Declared as array of references of type Foo*

 GetArray(Foo** &f, unsigned &size) const { f = m; size = mSize; } 

Gives me: Error: assignment Foo **' from incompatible type Foo *const[10] . Throwing mFoo to (Foo**) fixes the error, but IMHO, this is not elegant.

0
source share
3 answers

No one sent a response using std::array , but this is a very simple replacement:

 class Bar { std::array<Foo *, 10> m; public: std::array<Foo *, 10> & getArray() { return m; } std::array<Foo *, 10> const & getArray() const { return m; } }; 

It seems to me that this is much simpler than the hoops you need to jump to use a C-style version of the array

To avoid code duplication, you could typedef std::array<Foo *, 10> FooArray; .

The implementation technique of both const and non- const is a common template for access functions that return a link or pointer. (This is not required if your accessory is returned by value, of course).

+1
source

In most cases, I would like to use std::array or std::vector . If you decide to use a raw array, you can go with it like this:

 typedef int Foo; typedef Foo* (&FooPtrArrayRef)[10]; // to make the syntax less hairy class Bar { private: Foo* m[10]; public: // First way without using typedef Foo* (&getArray())[10] { return m; } // Nicer looking way with a typedef FooPtrArrayRef getArrayByRef() { return m; } }; int main() { Bar b; Foo* (&array)[10] = b.getArray(); std::cout << (sizeof(array) / sizeof(Foo*)) << '\n'; // Alternative using "size deduction" Foo* (&array2)[sizeof(b.getArray()) / sizeof(Foo*)] = b.getArray(); std::cout << (sizeof(array2) / sizeof(Foo*)) << '\n'; // MUCH nicer using the typedef FooPtrArrayRef array3 = b.getArrayByRef(); std::cout << (sizeof(array3) / sizeof(Foo*)) << '\n'; } 

The syntax is rather obscure, however.

The advantage of this approach is that it saves all the information about the type of array that you pass by reference. An obscure syntax is needed to avoid type merging with Foo** . By preserving the full type of the array, you retain the ability to know its size at compile time using the sizeof() operator.

+1
source

here is another approach that returns an array reference and current size as a tuple:

 #include <tuple> #include <functional> #include <algorithm> #include <iterator> #include <iostream> struct Foo {}; using FooBuffer = Foo*[10]; class Bar { public: Bar() : _m { nullptr } { _m[0] = new Foo; _m[1] = new Foo; _items = 2; } ~Bar() { for(auto fp : _m) delete fp; } std::tuple<FooBuffer&, size_t> getInfo() { return std::make_tuple(std::ref(_m), _items); } private: Foo* _m[10]; size_t _items; }; int main() { Bar b; auto info = b.getInfo(); FooBuffer& buf = std::get<0>(info); size_t items = std::get<1>(info); for(Foo** p = buf ; p != buf + items ; ++p) { std::cout << "Foo at " << std::hex << *p << std::endl; } return 0; } 
0
source

Source: https://habr.com/ru/post/1204029/


All Articles