【问题标题】:What exactly is decltype(std::get<0>(tup))?decltype(std::get<0>(tup)) 到底是什么?
【发布时间】:2020-10-11 07:22:14
【问题描述】:

我目前正在学习 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


    【解决方案1】:

    std::is_same/std::is_same_v 在 TMP 中非常有用,并且在寻找与其他类型相同的类型时,与 static_assert 结合使用时非常有用。

    通过以下代码,您可以看到std::get 为您提供了对元组元素的引用(由cppreference's page on std::get 确认),在本例中为int*&amp;,其中int* 是元素的类型.如果您使用它来初始化 another 变量,您将获得它的副本(因此不再引用 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&lt;decltype(std::get&lt;0&gt;(tup))&gt;::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_pointeris_same_v 代替is_same?带有_v 的那些是辅助元函数,它们为您提供非_v 元函数的value 成员。 remove_reference_tremove_reference 的工作方式类似,但提供了 type 成员。

    【讨论】:

      【解决方案2】:

      作为Enrico explained,你得到的类型是一个引用。 除了他的回答,我想说您可以更轻松地获得元组元素的实际类型:

      std::tuple_element_t<0, decltype(tup)>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-03-08
        • 2023-03-03
        • 2015-12-04
        • 2011-07-01
        • 2021-12-28
        • 1970-01-01
        • 2015-02-19
        相关资源
        最近更新 更多