-3

I don't know how to categorize this question precisely, so I'll just explain:

I was googling some stuff for an assignment, and I found what I was looking for, but among the results I checked, I found this one question where I saw so many things I didn't know of/understand: C++ Lambda capture private class member

//...
    bool dump_dvars()
    {
        fstream& refvar{ output_file };

        for_each(_array_start, _array_start + *_array_size,
            [&refvar](const void* dvar) -> void
        {
            //work with output_file
        });

        return true;
    }

private:
    void** _array_start;
    unsigned int* _array_size;
    fstream output_file;
};

I don't know what the specific names of each combination are, but I'd like to know what these do:

  • fstream& refvar{ output_file };
  • [&refvar]
  • (const void* dvar)
  • -> void
  • void**
  • unsigned int*

The ones concerning void; I was under the impression that void pointers should be avoided(oh hey, a pun :P), because I read things like the reply to this: List of pointers to different types of objects "Only use a void as a last and very,very dangerous solution."

So what's the use of having a pointer of type void, and a pointer-to-pointer of type void, and accessing the type "void" with lambda?? What does that even do? It's not a variable to fetch stored data from it, what is it accessing? And what would "output_file" do when it isn't assigned a type nor is it stored(so I guess it doesn't return anything, and it isn't returned so it doesn't look like a function), it doesn't have brackets so it doesn't need parameters - it's just an identifier standing there, what does it do? And what does it matter if your int-pointer is unsigned? Aren't all ints like a base class almost(I know int isn't a class) so you can point to another integer with any kind of int? All signed and unsigned integers have the same size when pointing to where in the memory it should be stored i.e. what address, it's just a question of what "direction" or value it will/can hold there.

EDIT:

Attempting to narrow the question down: How does accessing the type "void" work, and what does [&refvar] do?

Jack Of Blades
  • 495
  • 7
  • 16
  • _"And what would "output_file" do when it isn't assigned a type"_ - it is assigned a type, further down - `fstream output_file;` - the type is `fstream`. – davmac Apr 12 '18 at 15:06
  • 1
    (and beyond that, wow... you ask so many things and indicate a number of misunderstandings, to answer everything properly would require pages. Maybe try to narrow down your question). – davmac Apr 12 '18 at 15:07
  • I'm voting to close this as being too broad, as SO is for specific problems, not generalised grab-bags of questions as a substitute for reading a book/tutorial. – underscore_d Apr 12 '18 at 15:08
  • Read a good C++ textbook. –  Apr 12 '18 at 15:08
  • @davmac That's not what I meant. If I make a program which only(apart from includes and main, return 0) has one line: int a;, it effectively does nothing. Why would anyone do that? Refvar only calls that variable, it doesn't put it anywhere nor change it. – Jack Of Blades Apr 12 '18 at 15:15
  • @NeilButterworth Such as? – Jack Of Blades Apr 12 '18 at 15:18
  • 1
    @JackOfBlades [The Definitive C++ Book Guide and List](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) – Miles Budnek Apr 12 '18 at 15:20
  • @JackOfBlades ok, it's not what you meant, but it is what you said :) your terminology is wrong throughout which makes it difficult to understand your question (eg refvar doesn't "call" anything, its initialisation creates a reference to `output_file`, etc). Regarding your edit to narrow down the question: you need to properly edit the original question so that it no longer asks the plethora of questions that it does, not just tack an "edit" note at the end. – davmac Apr 12 '18 at 15:41

2 Answers2

0
fstream& refvar{ output_file };

Declares a local variable of type "reference to an fstream" and initializes it with a reference to the output_file member.

[&refvar]

Capture refvar for the lambda. In other words, the lambda stores a reference to refvar that can be accessed within the lambda body.

(const void* dvar)

The lambda argument list. This lambda can be called with a const void pointer (named dvar).

-> void

The lambda return type (void). Note that this "trailing return type" version is also possible for normal functions, but rarely used there.

The last ones are obvious pointer types.

As for "what do you do with the void pointer": Dereferencing the void pointer in C++

Max Langhof
  • 23,383
  • 5
  • 39
  • 72
0

Although Max Langhof's answer is satisfactory, I want to explain this to myself for future use(and maybe someone else might find this explanation even more straightforward or useful):

  1. fstream& refvar{ output_file };
  2. [&refvar]
  3. (const void* dvar)
  4. -> void
  5. void**
  6. unsigned int*

Answers:

  1. This actually returns the member variable "output_file" strangely enough(NOTE: if in doubt, try this in a small class).
  2. This is part of a "lambda function", which is like a callback function in javascript. [&refvar] takes "refvar" from outside of the lambda function and gives a reference to it to be used inside of the lambda function, solves scope trouble.
  3. A void-pointer can point to any kind of object(like Java's Object-type), but if you want it dereferenced, it can't do that, unless you type-cast it first to the desired type, and then dereference it. I still don't know why it was called dangerous though. Might have been that one-in-a-million situation where you have to.
  4. -> void is the return type of the lambda function, the -> is just how it's written, nothing to do with accessing a member.
  5. void** is, obviously, a void ptr-to-ptr, can be used the same way void* can be used, don't know if you have to type-cast it twice(once for each dereferencing, but try it out and see).
  6. I'm not entirely sure why the array size pointer was unsigned, but if the array wants a larger size(quantities can only be positive or 0, so makes sense to have a positive limit as big as it can get) then it can get it, and maybe a signed pointer can't point to an unsigned pointer.
Jack Of Blades
  • 495
  • 7
  • 16