I am currently learning metaprograming in C++, and I'm trying to see whether an element of a tuple is a pointer. I tried this approach:
int a = 3, b = 4;
auto tup = std::make_tuple(&a, b);
std::cout << std::is_pointer<decltype(std::get<0>(tup))>::value; //prints 0
I thought this was strange, so I examined the type clang deduced (I'm using clang-10), which is
__tuple_element_t<0UL, tuple<int *, int>
And it looks like some internal type.
Why do I get this weird type and what would be the proper way to get the actual type of an element of the tuple? I have only a solution which uses an intermediate auto variable, but is hardly optimal.
std::is_same/std::is_same_vcan be very helpful in TMP and, when looking for types being equal to other types, it's invaluable when used in conjunction withstatic_assert.With the following code you can see that
std::getgives you a reference to the element of the tuple (as confirmed by cppreference's page onstd::get), in this caseint*&, whereint*is the type of the element. If you use it to initialize another variable you get a copy of it (so no more reference forelem, justint*), just likeint x = r;definesxto be a copy ofrregardless ofrbeing a reference or not.As regards your attempt, the fact that the second
static_assertabove is passing, explains whystd::is_pointer<decltype(std::get<0>(tup))>::valueprintsfalse/0: that is a reference toint*, not anint*. On the other hand, the following does printtrue/1:See that I've used
is_pointer_vinstead ofis_pointerandis_same_vinstead ofis_same? Those with_vare helper metafunctions that give you thevaluemember of the non-_vmetafunctions.remove_reference_tworks similarly with respect toremove_reference, but giving thetypemember.