#include <iostream>
// Contains the actual value for one item in the tuple. The
// template parameter `i` allows the
// `Get` function to find the value in O(1) time
template<std::size_t i, typename Item>
struct TupleLeaf {
Item value;
};
// TupleImpl is a proxy for the final class that has an extra
// template parameter `i`.
template<std::size_t i, typename... Items>
struct TupleImpl;
// Base case: empty tuple
template<std::size_t i>
struct TupleImpl<i>{};
// Recursive specialization
template<std::size_t i, typename HeadItem, typename... TailItems>
struct TupleImpl<i, HeadItem, TailItems...> :
public TupleLeaf<i, HeadItem>, // This adds a `value` member of type HeadItem
public TupleImpl<i + 1, TailItems...> // This recurses
{};
// Obtain a reference to i-th item in a tuple
template<std::size_t i, typename HeadItem, typename... TailItems>
HeadItem& Get(TupleImpl<i, HeadItem, TailItems...>& tuple) {
// Fully qualified name for the member, to find the right one
// (they are all called `value`).
return tuple.TupleLeaf<i, HeadItem>::value;
}
// Templated alias to avoid having to specify `i = 0`
template<typename... Items>
using Tuple = TupleImpl<0, Items...>;
int main(int argc, char** argv) {
Tuple<int, float, std::string> tuple;
Get<0>(tuple) = 5;
Get<1>(tuple) = 8.3;
Get<2>(tuple) = "Foo";
std::cout << Get<0>(tuple) << std::endl;
std::cout << Get<1>(tuple) << std::endl;
std::cout << Get<2>(tuple) << std::endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKLy8gQ29udGFpbnMgdGhlIGFjdHVhbCB2YWx1ZSBmb3Igb25lIGl0ZW0gaW4gdGhlIHR1cGxlLiBUaGUgCi8vIHRlbXBsYXRlIHBhcmFtZXRlciBgaWAgYWxsb3dzIHRoZQovLyBgR2V0YCBmdW5jdGlvbiB0byBmaW5kIHRoZSB2YWx1ZSBpbiBPKDEpIHRpbWUKdGVtcGxhdGU8c3RkOjpzaXplX3QgaSwgdHlwZW5hbWUgSXRlbT4Kc3RydWN0IFR1cGxlTGVhZiB7CiAgICBJdGVtIHZhbHVlOwp9OwoKLy8gVHVwbGVJbXBsIGlzIGEgcHJveHkgZm9yIHRoZSBmaW5hbCBjbGFzcyB0aGF0IGhhcyBhbiBleHRyYSAKLy8gdGVtcGxhdGUgcGFyYW1ldGVyIGBpYC4KdGVtcGxhdGU8c3RkOjpzaXplX3QgaSwgdHlwZW5hbWUuLi4gSXRlbXM+CnN0cnVjdCBUdXBsZUltcGw7CgovLyBCYXNlIGNhc2U6IGVtcHR5IHR1cGxlCnRlbXBsYXRlPHN0ZDo6c2l6ZV90IGk+CnN0cnVjdCBUdXBsZUltcGw8aT57fTsKCi8vIFJlY3Vyc2l2ZSBzcGVjaWFsaXphdGlvbgp0ZW1wbGF0ZTxzdGQ6OnNpemVfdCBpLCB0eXBlbmFtZSBIZWFkSXRlbSwgdHlwZW5hbWUuLi4gVGFpbEl0ZW1zPgpzdHJ1Y3QgVHVwbGVJbXBsPGksIEhlYWRJdGVtLCBUYWlsSXRlbXMuLi4+IDoKICAgIHB1YmxpYyBUdXBsZUxlYWY8aSwgSGVhZEl0ZW0+LCAvLyBUaGlzIGFkZHMgYSBgdmFsdWVgIG1lbWJlciBvZiB0eXBlIEhlYWRJdGVtCiAgICBwdWJsaWMgVHVwbGVJbXBsPGkgKyAxLCBUYWlsSXRlbXMuLi4+IC8vIFRoaXMgcmVjdXJzZXMKICAgIHt9OwoKLy8gT2J0YWluIGEgcmVmZXJlbmNlIHRvIGktdGggaXRlbSBpbiBhIHR1cGxlCnRlbXBsYXRlPHN0ZDo6c2l6ZV90IGksIHR5cGVuYW1lIEhlYWRJdGVtLCB0eXBlbmFtZS4uLiBUYWlsSXRlbXM+CkhlYWRJdGVtJiBHZXQoVHVwbGVJbXBsPGksIEhlYWRJdGVtLCBUYWlsSXRlbXMuLi4+JiB0dXBsZSkgewogICAgLy8gRnVsbHkgcXVhbGlmaWVkIG5hbWUgZm9yIHRoZSBtZW1iZXIsIHRvIGZpbmQgdGhlIHJpZ2h0IG9uZSAKICAgIC8vICh0aGV5IGFyZSBhbGwgY2FsbGVkIGB2YWx1ZWApLgogICAgcmV0dXJuIHR1cGxlLlR1cGxlTGVhZjxpLCBIZWFkSXRlbT46OnZhbHVlOwp9CgovLyBUZW1wbGF0ZWQgYWxpYXMgdG8gYXZvaWQgaGF2aW5nIHRvIHNwZWNpZnkgYGkgPSAwYAp0ZW1wbGF0ZTx0eXBlbmFtZS4uLiBJdGVtcz4KdXNpbmcgVHVwbGUgPSBUdXBsZUltcGw8MCwgSXRlbXMuLi4+OwoKaW50IG1haW4oaW50IGFyZ2MsIGNoYXIqKiBhcmd2KSB7CiAgICBUdXBsZTxpbnQsIGZsb2F0LCBzdGQ6OnN0cmluZz4gdHVwbGU7CiAgICBHZXQ8MD4odHVwbGUpID0gNTsKICAgIEdldDwxPih0dXBsZSkgPSA4LjM7CiAgICBHZXQ8Mj4odHVwbGUpID0gIkZvbyI7CiAgICBzdGQ6OmNvdXQgPDwgR2V0PDA+KHR1cGxlKSA8PCBzdGQ6OmVuZGw7CiAgICBzdGQ6OmNvdXQgPDwgR2V0PDE+KHR1cGxlKSA8PCBzdGQ6OmVuZGw7CiAgICBzdGQ6OmNvdXQgPDwgR2V0PDI+KHR1cGxlKSA8PCBzdGQ6OmVuZGw7CiAgICByZXR1cm4gMDsKfQ==