Better_Software_Header_MobileBetter_Software_Header_Web

Find what you need - explore our website and developer resources

Tuple And Pair in C++ APIs?

A Simple Design Goal to Improve Your C++ APIs

if (auto result = atoi(str))
    std::cout << "got " << *result << std::endl;
else
    std::cout >> "failed to parse \" << str << "\" as an integer: " << "???" << std::endl;
auto result = atoi(str);
if (auto i = std::get_if<int>(&result))
    std::cout << "got " << i << std::endl;
else if (auto error = std::get_if<std::error_code>(&result)))
    std::cout << "failed to parse \" << str << "\" as an integer: " << error.message() << std::endl;
else
    std::cout << "oops, variant was in invalid state" << std::endl;
template <typename T>
class value_or_error {
    std::variant<T, std::error_code> m_v; // space-saving impl detail
public:
    explicit value_or_error(std::error_code e)
        : m_v(std::move(e)) {}
    explicit value_or_error(T t)
        : m_v(std::move(t)) {}

    std::error_code error() const {
        if (auto e = std::get_if<std::error_code>(&m_v))
            return *e;
        else
            return std::error_code();
    }

    T& operator *() { return std::get<0>(m_v); }
    T const& operator *() const { return std::get<0>(m_v); }

    explicit operator bool() const { return !error(); }
    bool operator !() const { return error(); }
};
if (auto result = atoi(str))
    std::cout << "got " << *result << std::endl;
else
    std::cout << "failed to parse \" << str << "\" as an integer: " << result.error().message() << std::endl;
template <typename Iterator>
struct insert_result {
    Iterator iterator;
    bool inserted;
};
auto result = set.insert(obj);
if (!result.inserted)
    *result.iterator = obj;
auto result = set.insert(obj);
if (!result.second) // or was it .first?! - I can never remember...
    *result.first = obj;
template <typename Iterator>;
struct equal_range_result {
    Iterator first;
    Iterator last;

    friend auto begin(const equal_range_result &r) { return r.first; }
    friend auto end(const equal_range_result &r) { return r.last; }
};
for (auto && [key, value] : map.equal_range(obj))
   // ...
auto v1 = ...;
//...
auto vN = ...;
for (auto &&e : zip(v1, ..., vN))
   // ...
for (auto && [e1, ..., eN] : zip(v1, ..., vN))
   // ...
// Qt 5:
typedef QPair<qreal, QColor> QGradientStop;
// Qt 6 (hopefully):
struct QGradientStop {
   qreal location;
   QColor colour;
};

About KDAB


6 Comments

27 - Oct - 2016

Kevin Kofler

28 - Oct - 2016

Philippe

5 - Feb - 2017

Vicente Botet

11 - Feb - 2017

Aurelien

27 - Aug - 2017

einpoklum

5 - Feb - 2018

alfC

struct insert_result {
    std::set::iterator iterator;
    bool inserted;
} insert(std::set& set, double const& v){
    auto p = set.insert(v);
    return {p.first, p.second};
}
01_NoPhoto

Marc Mutz

Former KDAB employee

Related Content

Learn Modern C++

Learn more