簡體   English   中英

通過索引c ++ 11訪問元組元素

[英]access tuple elements by index c++11

這不是秘密, std::get<i>(tuple)惹惱了許多程序員。

代替它,我想使用類似tuple[i]東西。

所以我嘗試模擬它。

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

template < int > struct index{};



template< char ... >
struct combine;

template<> struct combine<> : std::integral_constant< int , 0>{};


constexpr int ten(size_t p)noexcept
{
    return p == 0 ? 1 : 10 * ten(p-1);
}

template< char c, char ... t>
struct combine<c, t...> : std::integral_constant< int, (c - '0')*ten(sizeof...(t)) + combine<t...>::value > 
{ static_assert(c >= '0' && c <= '9', "only 0..9 digits are allowed");  };


template< char ... c >
constexpr auto  operator "" _index()noexcept 
{ 
    return index< combine<c...>::value >{}; 
}; 

template< class ... Args >
struct mytuple : public std::tuple<Args...>
{
    using std::tuple<Args...>::tuple;

    template< int i >
    auto& operator []( index<i> ) noexcept
    {
        return std::get< i > ( static_cast< std::tuple<Args...> & >(*this) );
    }

    template< int i>
    auto const& operator [](index<i> )const noexcept
    {
        return std::get< i >(static_cast< std::tuple<Args...> const& >(*this) );
    }

};


int main()
{
     static_assert( combine<'1','2','3','4'>::value == 1234, "!");


     static_assert( std::is_same< index<785>, decltype( 785_index ) > {}, "!");

     using person = mytuple< std::string, int, double, char>;

     person s = std::make_tuple("Bjarne Stroustrup", 63, 3.14, '7' );
     auto name = s[ 0_index ];
     auto old  = s[ 1_index ];
     auto number = s[ 2_index ];
     auto symbol = s[ 3_index ];

     std::cout << "name: "   << name << '\t'
               << "old: "    << old << '\t'
               << "number: "  << number<< '\t'
               << "symbol: " << symbol<< '\t'
               << std::endl;
}

問:這段代碼出了什么問題? 即此代碼是否可用? 如果可用,為什么不這樣實現std::tuple

我不太確定您的具體問題是什么,但似乎您正在尋找一點方便。 以下使用占位符(以_1開頭)來簡化代碼:

#include <iostream>
#include <type_traits>
#include <tuple>
#include <functional>

template< class ... Args >
struct mytuple : public std::tuple<Args...>
{
    using std::tuple<Args...>::tuple;

    template< typename T >
    auto& operator []( T ) noexcept
    {
        return std::get< std::is_placeholder<T>::value - 1 >( *this );
    }

    template< typename T >
    auto const& operator []( T ) const noexcept
    {
        return std::get< std::is_placeholder<T>::value - 1 >( *this );
    }
};

int main()
{
    using person = mytuple< std::string, int, double, char>;

    using namespace std::placeholders;

    person s = std::make_tuple("Bjarne Stroustrup", 63, 3.14, '7' );
    auto name = s[ _1 ];
    auto old  = s[ _2 ];
    auto number = s[ _3 ];
    auto symbol = s[ _4 ];

    std::cout << "name: "   << name << '\t'
              << "old: "    << old << '\t'
              << "number: "  << number<< '\t'
              << "symbol: " << symbol<< '\t'
              << std::endl;
}

這里的竅門是要知道std::is_placeholder<T>是從std::integral_constant<int,N>派生的:)希望您喜歡它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM