gpt4 book ai didi

c++11 - 对于 std::tuple,如何按类型获取数据,如何按索引获取类型?

转载 作者:行者123 更新时间:2023-12-04 17:01:28 35 4
gpt4 key购买 nike

标题说:给定一个 std::tuple,我想

  • 获取给定类型的第一个元素
  • 获取第 i 个元素的类型

  • 有没有解决办法 STL提供 ?或 解决方法 ?有人可以尝试完成我的代码吗?
    #include <tuple>

    int main ()
    {
    std::tuple<int,char,int> mytuple (10,'a', 5);

    // how to get the first int element here? (10)
    // int x = std::get_me_the_first<int>(mytuple);

    // how to get the type of the second element here?
    // std::get_me_type_of<1> ch = 'x';

    return 0;
    }

    编译成这样:
    g++ -std=c++11 -Wall main.cpp -o main

    最佳答案

    按类型(而不是索引)从元组中获取值

    从 C++11 开始,没有 STL 方法来获取类型 T 的元组的第一个元素。 .
    在 C++14 中,应该有一种方法可以使用 std::get 的新重载做你想做的事。 ISO 文件位于此处 N3404和这里 N3670 .

    您可以在 C++11 中使用以下命令执行此操作:

    #include<tuple>
    #include<type_traits>
    #include<string>
    #include<iostream>

    template<int Index, class Search, class First, class... Types>
    struct get_internal
    {
    typedef typename get_internal<Index + 1, Search, Types...>::type type;
    static constexpr int index = Index;
    };

    template<int Index, class Search, class... Types>
    struct get_internal<Index, Search, Search, Types...>
    {
    typedef get_internal type;
    static constexpr int index = Index;
    };

    template<class T, class... Types>
    T get(std::tuple<Types...> tuple)
    {
    return std::get<get_internal<0,T,Types...>::type::index>(tuple);
    }

    我把它托管在 Ideone here ,但这是我对后代的测试功能
    int main()
    {
    std::tuple<int, double, std::string> test{1, 1.7, "test"};
    std::cout<<"get<0> == get<int> :"<< (std::get<0>(test) == get<int>(test))<< "\n";
    std::cout<<"get<1> == get<double> :"<<(std::get<1>(test) == get<double>(test))<< "\n";
    std::cout<<"get<2> == get<std::string> :"<<(std::get<2>(test) == get<std::string>(test))<< "\n";
    }

    基于@Yakk 扩展它以支持一个类型的多个实例以及要在元组中测试的谓词的想法,他提供了下面的代码(也托管在 Ideone here 上)
    请注意:在 C++14 中 std::get 的新重载不允许元组中有多个相同类型的实例。相反,它会发出编译错误。此外,C++14 版本也不支持谓词。
    //Include same headers as before
    template<bool b, typename T=void>
    using EnableIf = typename std::enable_if<b,T>::type;

    template<int Index, template<typename T>class Search, int Which, typename, class First, class... Types>
    struct get_internal:
    get_internal<Index + 1, Search, Which, void, Types...>
    {};

    template<int Index, template<typename T>class Search, int Which, class First, class... Types>
    struct get_internal<Index, Search, Which, EnableIf<!Search<First>::value>, First, Types...>:
    get_internal<Index + 1, Search, Which, void, Types...>
    {};
    template<int Index, template<typename T>class Search, int Which, class First, class... Types>
    struct get_internal<Index, Search, Which, EnableIf<Search<First>::value>, First, Types...>:
    get_internal<Index + 1, Search, Which-1, void, Types...>
    {};
    template<int Index, template<typename T>class Search, class First, class... Types>
    struct get_internal<Index, Search, 0, EnableIf<Search<First>::value>, First, Types...>:
    std::integral_constant<int, Index>
    {};

    template<template<typename>class Test, int Which=0, class... Types>
    auto get(std::tuple<Types...>& tuple)->
    decltype(std::get<get_internal<0,Test,Which,void,Types...>::value>(tuple))
    {
    return std::get<get_internal<0,Test,Which,void,Types...>::value>(tuple);
    }
    template<template<typename>class Test, int Which=0, class... Types>
    auto get(std::tuple<Types...> const& tuple)->
    decltype(std::get<get_internal<0,Test,Which,void,Types...>::value>(tuple))
    {
    return std::get<get_internal<0,Test,Which,void,Types...>::value>(tuple);
    }
    template<template<typename>class Test, int Which=0, class... Types>
    auto get(std::tuple<Types...>&& tuple)->
    decltype(std::move(std::get<get_internal<0,Test,Which,void,Types...>::value>(tuple)))
    {
    return std::move(std::get<get_internal<0,Test,Which,void,Types...>::value>(tuple));
    }

    template<typename T>
    struct is_type {
    template<typename U>
    using test = std::is_same<T,U>;
    };

    template<class T, int Which=0, class... Types>
    T& get(std::tuple<Types...>& tuple)
    {
    return get<is_type<T>::template test,Which>(tuple);
    }
    template<class T, int Which=0, class... Types>
    T const& get(std::tuple<Types...> const& tuple)
    {
    return get<is_type<T>::template test,Which>(tuple);
    }
    template<class T, int Which=0, class... Types>
    T&& get(std::tuple<Types...>&& tuple)
    {
    return std::move(get<is_type<T>::template test,Which>(tuple));
    }

    获取元组中第 n 个元素的类型

    有一种方法可以获取第 n 个元素的类型。 std::tuple_element<n, decltype(tuple)>::type (感谢@syam)是元组的第 n 个元素的类型。

    关于c++11 - 对于 std::tuple,如何按类型获取数据,如何按索引获取类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16594002/

    35 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com