I have a custom type (which I can extend):
struct Foo { int a; string b; };
How can I create an instance of this object that can be assigned std::tie , i.e. std::tuple links?
Foo foo = ...; int a; string b; std::tie(a, b) = foo;
Failed Attempts:
Overloading the assignment operator for tuple<int&,string&> = Foo not possible, because the assignment operator is one of the binary operators that must be members of the left-side object.
So I tried to solve this problem by running the appropriate tuple conversion operator . The following versions failed to complete:
operator tuple<int,string>() constoperator tuple<const int&,const string&>() const
They lead to an assignment error, saying that " operator = not overloaded for tuple<int&,string&> = Foo ". I think this is due to the fact that "converting to any pattern X + the pattern parameter X for the operator =" does not work together, only one of them at once.
Failed attempt:
Therefore, I tried to implement a conversion operator for the exact type of binding :
operator tuple<int&,string&>() const Demooperator tuple<int&,string&>() Demo
The assignment now works, because the types are now (after conversion) exactly the same, but this will not work for the three scenarios that I would like to support:
- If the connection is related to variables of different but convertible types (i.e. change
int a; to long long a; on the client side), it fails, because the types must fully match. This contradicts the usual use of tuple assignment in a link tuple, which allows you to convert types. (one) - The conversion operator should return a link for which lvalue references should be given. This will not work for temporary values or constant members. (2)
- If the conversion operator is not const, assignment also fails for
const Foo on the right side. To implement the const version of the transformation, we need to remove the constant of the const object members. This is ugly and can be abused, resulting in undefined behavior.
I see only an alternative in providing my own tie function + class function along with my "binding-related" objects, which makes me duplicate std::tie functions that I don’t like (not that I find it difficult, but it’s not good for him do it).
I think the conclusion at the end of the day is that this is one of the drawbacks of implementing the library for tuples only. They are not as magical as we would like.
EDIT:
As it turned out, there is no real solution to all of the above problems. A very good answer would explain why this is not solvable. In particular, I would like someone to shed light on why "unsuccessful attempts" cannot work.
(1): A terrible hack is to write the transformation as a template and convert to the requested member types in the conversion operator. This is a terrible hack because I don’t know where to store these converted elements. In this demo, I use static variables, but it is not thread-reentrant.
(2): You can apply the same hacking as in (1).