Search code examples
c++c++11return-valuestd-tie

Are there downsides with using std::tie for golang-like error-handling while also returning a result? (C++11)


In go a common way to do error handling and still return a value is to use tuples.

I was wondering if doing the same in C++ using std::tie would be a good idea when exceptions are not applicable.

like

std::tie(errorcode, data) = loadData();
if(errorcode)
  ...//error handling

Are there any downsides to doing so (performance or otherwise)? I suppose with return value optimization it doesn't really make a difference but maybe I'm wrong.

One potential problematic case that I could see is the use in a cross-compiler API but that's not specific to this use.

The current way I do this is

errorcode = loadData(&data);
if(errorcode)
  ...//error handling

but that allows to pass in a value for data.

The errorcode itself is something that is already defined and that I can't change.

Edit: I'm using/have to use C++11


Solution

  • Sometimes output parameters are very handy. Suppose that loadData returns std::vector<T> and is called in a loop:

    std::pair<ErrorCode, std::vector<T>> loadData();
    
    for (...) {
        ErrorCode errorcode;    
        std::vector<T> data;
        std::tie(errorcode, data) = loadData();
    }
    

    In this case loadData will have to allocate memory on each iteration. However, if you pass data as the output parameter, previously allocated space can be reused:

    ErrorCode loadData(std::vector<T>&);
    
    std::vector<T> data;
    for (...) {
        ErrorCode errorcode = loadData(data);
    }
    

    If the above is of no concern, then you might want to take a look at expected<T, E>. It represents either

    • a value of type T, the expected value type; or
    • a value of type E, an error type used when an unexpected outcome occurred.

    With expected, loadData() signature might look like:

    expected<Data, ErrorCode> loadData();
    

    C++11 implementation is available: https://github.com/TartanLlama/expected