LB-- / utf

My personal C++14 UTF-8 library in the public domain.
The Unlicense
9 stars 3 forks source link

Change pair to struct with named members #1

Open LB-- opened 8 years ago

LB-- commented 8 years ago

https://www.kdab.com/tuple-pair-cpp-apis/

mosra commented 8 years ago

Interesting discussion point.

In my APIs I prefer pair/tuple over struct because std::tie() can be used on it and then I can name, reorder or retype the members as I like. That makes of course sense only if it is clear which member is which (e.g. it's either intuitively clear or the types are different that there is no possibility in mixing them up). Another point is that when using std::tie() the return type is basically anonymous set of other types, which makes the API surface area smaller -- no need to document yet another trivial struct.

On the other hand, std::*map::insert()'s return type (or its behavior in general) is just bad. I am angry every time I come across it.

LB-- commented 8 years ago

I agree about std::tie, and I've been wondering if there is a way to keep it working for custom structures using some boilerplate or something.

mosra commented 8 years ago

Structured bindings in C++17 should solve that.

Otherwise, I think that maybe just a conversion operator could do it?

#include <tuple>

struct MyReturnType {
    void* a; int b; double c;

    operator std::tuple<void*&, int&, double&>() { return std::tie(a, b, c); }
};

std::tuple<void*, int, double> foo1() { return std::make_tuple(nullptr, 3, 1.27); }
MyReturnType foo2() { return {nullptr, 3, 1.27}; }

int main() {
    void* first;
    int second;
    double third;
    std::tie(first, second, third) = foo1();
    std::tie(first, second, third) = foo2();
}

I tried to make the conversion operator const and return just a standard tuple, but neither Clang nor GCC wanted to eat it.

mosra commented 8 years ago

Funny that in this case foo2() combines the advantages of both, usable with std::tie() and without the annoying std::make_tuple call needed pre-C++17 because the tuple constructor is explicit.