Jam*_*ith 5 c++ types template-meta-programming stdtuple
我目前正在学习 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
Run Code Online (Sandbox Code Playgroud)
我觉得这很奇怪,所以我检查了推断的类型 clang(我使用的是 clang-10),这是
__tuple_element_t<0UL, tuple<int *, int>
Run Code Online (Sandbox Code Playgroud)
它看起来像是某种内部类型。
为什么我会得到这种奇怪的类型以及获取元组元素的实际类型的正确方法是什么?我只有一个使用中间auto变量的解决方案,但几乎不是最佳的。
std::is_same/std::is_same_v在 TMP 中非常有用,并且在寻找与其他类型相等的类型时,与static_assert.
使用以下代码,您可以看到它std::get为您提供了对元组元素的引用(如cppreference 上的页面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*&>,"");
}
Run Code Online (Sandbox Code Playgroud)
至于你的尝试,第二的事实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))>>;
Run Code Online (Sandbox Code Playgroud)
看到我使用了is_pointer_v代替is_pointer和is_same_v代替了is_same吗?那些_v是辅助元函数,它们为您提供value非_v元函数的成员。 remove_reference_t与 类似remove_reference,但给予type成员。