我目前正在学习 C++ 元编程,我正在尝试查看元组的元素是否是指针。我尝试过这种方法:
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
我觉得这很奇怪,所以我检查了推导出来的 clang 类型(我使用的是 clang-10),它是
__tuple_element_t<0UL, tuple<int *, int>
它看起来像是某种内部类型。
为什么我会得到这种奇怪的类型?获取元组元素的实际类型的正确方法是什么?我只有一个使用中间
auto
变量的解决方案,但很难说是最佳的。
std::is_same
/std::is_same_v
在 TMP 中非常有帮助,当寻找与其他类型相同的类型时,与 static_assert
结合使用是非常有价值的。
通过以下代码,您可以看到
std::get
为您提供了对元组元素的引用(由 std::get
上的 cppreference 页面确认),在本例中为 int*&
,其中 int*
是类型的元素。如果您使用它来初始化 另一个 变量,您将获得它的副本(因此不再引用 elem
,只需 int*
),就像 int x = r;
将 x
定义为 r
的副本一样r
是否为参考。
#include <type_traits>
#include <tuple>
int main() {
int a = 3, b = 4;
auto tup = std::make_tuple(&a, b);
auto elem = std::get<0>(tup);
static_assert(std::is_same_v<decltype(elem), int*>,"");
static_assert(std::is_same_v<decltype(std::get<0>(tup)), int*&>,"");
}
关于您的尝试,上面的第二个
static_assert
正在通过,这一事实解释了为什么std::is_pointer<decltype(std::get<0>(tup))>::value
打印false
/0
:这是对int*
的引用,而不是
int*
。另一方面,以下会打印true
/1
:
std::cout << std::is_pointer_v<std::remove_reference_t<decltype(std::get<0>(tup))>>;
看到我用
is_pointer_v
代替 is_pointer
和 is_same_v
代替 is_same
吗?那些带有 _v
的辅助元函数为您提供非 value
元函数的 _v
成员。 remove_reference_t
与 remove_reference
的工作方式类似,但给予 type
成员。
正如 Enlico 解释的那样,您获得的类型是参考。 除了他的回答之外,我想说您可以通过以下方式更轻松地获取元组元素的实际类型:
std::tuple_element_t<0, decltype(tup)>