decltype(std::get<0>(tup))到底是什么?

问题描述 投票:0回答:2

我目前正在学习 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
变量的解决方案,但很难说是最佳的。

c++ types template-meta-programming stdtuple
2个回答
10
投票

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
成员。


4
投票

正如 Enlico 解释的那样,您获得的类型是参考。 除了他的回答之外,我想说您可以通过以下方式更轻松地获取元组元素的实际类型:

std::tuple_element_t<0, decltype(tup)>
© www.soinside.com 2019 - 2024. All rights reserved.