Live data from Hacker News

Returning multiple values from functions in C++

eli.thegreenplace.net

31–40 of 67 posts

Re: Returning multiple values from functions in C++

#31
post #27

I know it's mentioned specially in the article but the C programmer in me immediately wants to use structs. They don't need to be complex or long lived or even initialized. And as a bonus there's no heap involved anywhere. Either that or just bail out of c++ and use go.

Yeah, same here, a president of a local Duff's decice fanclub, but you have to admit that proposed C++ 17 feature is pretty nice: ... foo() { return { 1, "bar", false }; } auto { i, s, b } = foo(); It's a syntax sugar, granted, and they could push it further by adopting tuples as a native language construct with some shorthand notation (e.g. [...]), but the idea is nice.

Sweet!

Although I still cannot believe it took C++ like 30 years to come up with this.

Re: Returning multiple values from functions in C++

#32
post #25
post #19

Earlier quoted context omitted.

I prefer to use generic structures (tuples, pairs etc.) or return proper type. One time structs are usually redeclared on multiple places. It is really hard maintain such code.

> One time structs are usually redeclared on multiple places. It is really hard maintain such code. Well, if you don't need forward declarations, you can define structs inline in function signature: #include struct ret { int a; int b} hello(int c) { return (struct ret){ c, c + 1 }; } int main(int argc, char **argv) { struct ret result = hello(2); printf("%d %d", result.a, result.b); } I'm not sure how portable it is…

I meant something like that:

  struct x {int a, char* b}
  x foo();
  // a lot of code
  struct y {char* y, int x}
  y bar();
  //another header
  struct z {bool a, int b, char* c}
  z foo2();
It is ussually the same data structure, but someone was lazy to define it properly.

Re: Returning multiple values from functions in C++

#33

I am a bit surprised exceptions were not mentioned in the context of returning an error value.

The idea was to show things that actually make sense as return values / statuses rather than exceptions. I surely wouldn't throw an exception for "getline reached EOF"

Re: Returning multiple values from functions in C++

#34
post #29

The problem with deconstructing a tuple is that you can easily make mistake about the order of its members. The struct is a much better solution to me, and you can go over the problem of the weirdly named one-off struct by using the iod library ( https://github.com/matt-42/iod ): foo() { return D(_id = "test", _age = "42" }; } auto r = foo(); std::cout

Meaningful names would be nice.

In C++ iterating over a map items you get a pair with ->first() and ->second() methods instead of key / value.

Python has named tuples which can work both ways.

Re: Returning multiple values from functions in C++

#35
For a moment, I thought they had added true multiple value return to C++. I am sooo glad they didn't. The lisp folks added it way back, and it has been an ugly scar on the language ever since. Why do real multi-value returns suck? because they don't compose well, they're awkward as all heck to use, and require wrapping certain function calls in really weird constructs. The PROPER way to do multiple values is to return a data structure and pattern match against it. Of course, lisp has support for this, multi-value return was just an optimization hack. WHICH YOU SHOULD NO LONGER USE!

Re: Returning multiple values from functions in C++

#36
post #15

Ada has in, out and in/out parameters which adds a little more semantic to C and C++'s pointer parameters. Author mentions Common Lisp's multiple values, and one of the main feature of multiple values is that they are optional: the caller does not need to use secondary values. Even though floor returns 2 values, the following is a valid expression: (+ (floor x) 2) Only the primary value is used. A compiler typically…

Sometimes Lisp can get annoying though. I've used libraries where a function might return 5-6 values and I only need the first and last. I need to bind all of them and then (declare (ignore...)) the useless bits otherwise I get compiler warnings.

It's an annoyance, because I always feel the general ethos of Lisp is to eliminate tedious typing and multiple value returns frequently add a lot of cruft.

Re: Returning multiple values from functions in C++

#37

For a moment, I thought they had added true multiple value return to C++. I am sooo glad they didn't. The lisp folks added it way back, and it has been an ugly scar on the language ever since. Why do real multi-value returns suck? because they don't compose well, they're awkward as all heck to use, and require wrapping certain function calls in really weird constructs. The PROPER way to do multiple values is to retur…

It's funny, your comment uses "true MRV" for language-level special-casing by opposition to a matched (or even just python-style unpacked) data-structure, whereas I've always thought the latter was "true MRV".

Either way, we do agree on MRV being a language-level special case being a hack. Even PHP isn't that bad — though the unpacking is macro-ish bleh.

Re: Returning multiple values from functions in C++

#38
post #12

Earlier quoted context omitted.

std::tuple is essentially an "anonymous" struct -- there's no allocation involved

But the members inside don't have proper names.

That's rarely a problem where MRV makes sense. Though you could always fix it by using anonymous structs whose fields are both named and positional (similar to Python's namedtuples)

Re: Returning multiple values from functions in C++

#39
post #8
post #4

Earlier quoted context omitted.

Unfortunately the currently available solution (boost::optional) performs enough worse that the difference can be measured in a simple implementation of "wc -l". Consider the following code: #include #include #include using namespace std; using namespace boost; optional getline_(istream &st) { std::string line; if(getline(st, line)) return line; return none; } int main() { int lines = 0; while(getline_(cin)) lines++;…

That's not the fault of optional though. It's because with the optional version you're creating (and destroying) a new string each iteration of the loop. Something like this (untested) should be much closer to the non-optional version: #include #include #include using namespace std; using namespace boost; optional getline_(istream &st, string& line) { if(getline(st, line)) return line; return none; } int main() { int…

Which more or less removes any benefit for using optional, unfortunately.

Re: Returning multiple values from functions in C++

#40

For a moment, I thought they had added true multiple value return to C++. I am sooo glad they didn't. The lisp folks added it way back, and it has been an ugly scar on the language ever since. Why do real multi-value returns suck? because they don't compose well, they're awkward as all heck to use, and require wrapping certain function calls in really weird constructs. The PROPER way to do multiple values is to retur…

Multiple values are not "just" an optimization hack, they are designed to be convenient to use. I don't know which construct you find "weird". Multiple-value-bind is a descriptive name which is long to type but this does not matter (type m-v-b + auto-complete).

Typical example: you read a line in a file. The line you get is terminated either by a newline character or by the end-of file. The implementation of read-line[1] must know if you reached end of file or not, but most of the time, you don't care about it. Sometimes, you want to know, and then you can take the secondary value (missing-newline-p). I like the fact that I can focus on the primary value without caring about other ones when I want.

[1] http://clhs.lisp.se/Body/f_rd_lin.htm

Post reply on HN