Skip to main content

Tuples: are they useful?


In some languages there is such a thing as tuple which makes real to write such code (this time it's in python):


def f(x):
 #   do stuff return (True, modified_string)

success, modified_string = f(something) 

C++ hadn't such feature until C++11. That was one of the reasons to pass variable as referenced argument, which ended up creating huge code bases that have unused arguments in it's functions. That happened in order to save revers compatibility and allow clients to use stable interfaces to access libraries without checking the version of dynamically attached library in order to use correct functions.


The python example that was previously shown returns two values using tuple mechanism. Tuple allows to return as many values from a functions as user would like to.


    auto GetValue = [](int row, int col) {
        return make_tuple(0, 42);
    };

    int error_code = -1;
    int value = -1;
    tie(error_code, value) = GetValue(row, column);

    if (error_code == E_OK)
        panel.UpdateValue(row, column, value);

Such notation saves you a lot of effort and lowers complexity of code base when you need to signal that function have failed and there is no way to do so using single return value.

Tuple is a template STL class that uses variadic template definition in order to be able to create such container able to store as many values as you need. It's defined on compile time, so be careful using them through many layers of functions. I would say that usages of tuple is local functions and usage is to store or pass some independent values that in other way would be linked with a structure. From viewpoint of design you don't need to be worry about something that doesn't have a name, by using structure user eventually would have a lot of service structures in namespaces those purpose are linking together some values, error codes and optional variables.

Don't create service code that is used in few places, instead use tuple and keep important logic free of overheads like unnecessary structures and functions that are broken down into multiple smaller ones just to be able to get all the info client would need in order to work with your code.

By the way in C++17 this semantic is going to be updated and be more even more clear allowing to write next code.

    auto GetValue = [](int row, int col) {
        return tuple(0, 42);
    };
   
    int error_code = -1;
    int value = -1;
    auto [error_code, value] = GetValue(row, column);
    if (error_code == E_OK)
        panel.UpdateValue(row, column, value);

All this little tricks will help in maintaining code bases applying SOLID principles and trying to make it's model and semantics more strict to avoid possible mistakes.

Popular posts from this blog

Templates and how to fold them

Variadic templates appeared in C++11 to cover such cases when you would have a template functions that could have a numerous members of different types. Doesn't it remind you of variadic functions that uses va_start, va_arg, va_end and so others? Cause it should be.


Extend your list of debug tools with Sanitizers

How many ways to check if code is OK do you know? Probably the one would make a list with debuggers, logging, static/dynamic checkers, profilers and some other tools. The tools the one has in the list are there cause they've been checked with a time. They don't cover all the possible cases of mistakes that could be made during coding phase of a project, but they cover necessary minimum. Today we will try to extend our tool set with a young tools that already got into clang and if you have clang on your machine you can give it a try.