4 ms·
Well, the authoritative answer to "which types are contained in this tuple-like type" is std::tuple_element(_t). That's exactly what the std::apply machinery re
by MauranKilom 5y ago
Well, the authoritative answer to "which types are contained in this tuple-like type" is std::tuple_element(_t). That's exactly what the std::apply machinery relies on, which is why it's pretty convenient to build things around that.
Your suggestion fails for e.g. std::array, which is also tuple-like:
https://godbolt.org/z/qYhdfjrY3 https://godbolt.org/z/qYhdfjrY3
User-defined types can also specialize the required templates to opt-in to tuple-like behavior. In fact, doing so enables structured binding support, so it's not unlikely to see something like
Vec3 getCoords();
auto [x, y, z] = getCoords();
(where Vec3 specializes std::tuple_element etc.), and you wouldn't want your tuple printing code to error out when given a Vec3 either. In fact, Vec3 might not even be a template in the first place!
- addaon 5y agoThat all makes sense, I agree totally. One of the challenges with this sort of unmotivated code (unmotivated in a literal sense, not a derogatory sense -- we don't know what's motivating it) is that it's very hard to know how general a solution to design. I love the C++ template universe when things "just work," but it's very easy to get into a cycle where just a /bit/ more complexity gets you a /bit/ more generality -- only to realize that after beautifully polishing that modular code, you only use it in one or two contexts. std::apply is a good example of putting that generality and complexity into the standard library; if a caller can then use that directly, even with loss of generality, that's usually my preference. If nothing else, it means folks encountering the caller will have fewer layers to understand, and many fewer non-standard layers.