I usually create custom structs
when grouping values of different types together. This is usually fine, and I personally find the named member access easier to read, but I wanted to create a more general purpose API. Having used tuples extensively in other languages I wanted to return values of type std::tuple
but have found them much uglier to use in C++ than in other languages.
What engineering decisions went into making element access use an integer valued template parameter for get
as follows?
#include <iostream>
#include <tuple>
using namespace std;
int main()
{
auto t = make_tuple(1.0, "Two", 3);
cout << "(" << get<0>(t) << ", "
<< get<1>(t) << ", "
<< get<2>(t) << ")\n";
}
Instead of something simple like the following?
t.get(0)
or
get(t,0)
What is the advantage? I only see problems in that:
- It looks very strange using the template parameter like that. I know that the template language is Turing complete and all that but still...
- It makes indexing by runtime generated indices difficult (for example for a small finite ranged index I've seen code using switch statements for each possibility) or impossible if the range is too large.
Edit: I've accepted an answer. Now that I've thought about what needs to be known by the language and when it needs to be known I see it does make sense.
get<N>
). – Cornetcyt.get(rand(3))
have at compile-time? – Yogistd::get
handlesstd::pair
,std::array
,std::tuple
andstd::variant
transparently. This can be beneficial for generic code, allowing the type of the set to change without requiring special treatment. – SubalpineWhy use that mechanism for implementing them if it imposes such a severe restriction on their use?
No that's the point. If you decide at runtime to accesses element2
then you are deciding at runtime the type of element you are interacting with (as each index can be a different type). C++ is strongly typed so you can not have a situation were the type is not known until runtime. All type information must be resolved at compile time (as this is info is thrown away before the application is run). If you want to each index to be the same type usestd::vector
! – Peculiarity