Alternatives to Std::tuple for returning more than one value from a function

Hello,

I would like to know if there is an alternative to std::tuple and passing by reference for returning more than one value from a function. One value would be an integer as an error trapping return value and the others would be the function return values. I am looking for a concise way of doing this that would not require excess code lines. I currently have something like this:
if(func(param, param&) == 0)
{do this with param&;)

I would like to retain this syntax in some way. Can anyone help me out?
Could you elaborate a little more on how your desired method would work? I'm not sure what it is doing that would be different than passing by reference and returning an error code.
Then do it the way the language is designed: use references or tuples.

1
2
3
int code;
int response;
do_query( code, response );
1
2
3
int code;
int response;
std::tie( code, response ) = do_query();

Both are easily readable.
Why do you consider passing by reference to make the code harder to understand? It's an absolutely basic, everyday aspect of C++ that any developer should be able to understand at a glance.
Last edited on
C++ is moving in the direction of that tie() approach: C++17 already includes the new "destructuring" syntax that declares variables on the same line:
 
auto [code, response] = do_query();


after all, pass by non-const reference is an "in/out" parameter: https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#f17-for-in-out-parameters-pass-by-reference-to-non-const
Last edited on
I'm writing this program for future use by college students. In the college courses they teach where I am, they teach nothing about error trapping or any "good code-making" techniques. They don't teach passing by reference until the mid-first sophomore semester. And it's all in the console program environment. So yes, code presentation and organization matter to me a lot. Thanks for the info. I will consider that auto command.
I will consider that auto command.

that auto command is not yet supported by any released compilers, I just showed it as illustration that returning a pair or a tuple is the most future-proof approach.
It's a very sad truth that error checking is largely ignored in computer programming classes. When you're dealing with hardware, you really have no choice.

Even though your students haven't learned about passing by reference, they can still call functions that do it. You'll just have to explain to them that such a thing exists. As for the library, I suggest you follow a pattern like:
bool function(const InParams &in, OutParams &out);
The functions always return true on success and false on error. In addition, I'd include a thread-specific error variable:
struct Error {
int code;
string description;
stringstream context;
};
Error error;
Some people may gasp at the idea of a global, but it's really just following the errno concept from the C standard library.
- code is a numeric code like with errno. Each function sets it when there's an error.
- description is a text description of the error that happened.
- context says what was going on when the error happened. The nice thing about context is that if A() calls B() which calls C() which has an error, then each can set the context on the way up. Where I work, each function sets the context within that function. So A() might contain:
1
2
3
4
if (!B(bparam)) {
    error.context << "A(" << aParams << ')';
    return false;
}

This turns out to be a really powerful debugging tool. If yoused consistently, then when an error occurs, the context will say exactly what happened, where, and how you got there.

Does all this involve a lot of code? You bet it does! But that's what real code is. It involves a huge amount of error checking.

The other possibility is to use exceptions, but if the students haven't learned about call by reference, I doubt that they are ready for exceptions.
Topic archived. No new replies allowed.