decltype(std::get<0>(tup)) 究竟是什么?
What exactly is decltype(std::get<0>(tup))?
我目前正在学习 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
.[=44 结合使用时非常有用=]
通过以下代码,您可以看到 std::get
为您提供了对元组元素的引用(由 cppreference's page on std::get
确认),在本例中为 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
的是辅助元函数,它们为您提供非 _v
元函数的 value
成员。 remove_reference_t
与 remove_reference
的工作方式类似,但给出了 type
成员。
作为,您得到的类型是一个参考。
除了他的回答,我想说你可以更容易地得到元组元素的实际类型:
std::tuple_element_t<0, decltype(tup)>
我目前正在学习 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
.[=44 结合使用时非常有用=]
通过以下代码,您可以看到 std::get
为您提供了对元组元素的引用(由 cppreference's page on std::get
确认),在本例中为 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
的是辅助元函数,它们为您提供非 _v
元函数的 value
成员。 remove_reference_t
与 remove_reference
的工作方式类似,但给出了 type
成员。
作为
std::tuple_element_t<0, decltype(tup)>