c++11 标准模板(STL)(std::pair)(八)获得pair中元素的类型

定义于头文件 <utility>

std::pair 是一个结构体模板,其可于一个单元存储两个相异对象。 pair 是 std::tuple 的拥有两个元素的特殊情况。

获得pair中元素的类型

std::tuple_element<std::pair>

template< std::size_t I, class T1, class T2 >
struct tuple_element<I, std::pair<T1, T2>>;

(C++11 起)

std::tuple_element 对 pair 的部分特化使用类 tuple 语法,提供 pair 元素类型的编译时访问。若 I >= 2 则程序为病式。

成员类型

成员类型 定义
type I == 0 则为 T1
I == 1 则为 T2

可能的实现

template<std::size_t I, typename T>
  struct tuple_element;
 
template<std::size_t I, typename T1, typename T2>
  struct tuple_element<I, std::pair<T1,T2> >
  {
     static_assert(I < 2, "std::pair has only 2 elements!");
  };
 
template<typename T1, typename T2>
  struct tuple_element<0, std::pair<T1,T2> >
  {
     using type = T1;
  };
 
template<typename T1, typename T2>
  struct tuple_element<1, std::pair<T1,T2> >
  {
     using type = T2;
  };

调用示例

#include <iostream>
#include <string>
#include <iomanip>
#include <complex>
#include <tuple>
#include <typeinfo>

struct Cell
{
    int x;
    int y;

    Cell() = default;
    Cell(int a, int b): x(a), y(b) {}
    bool operator ==(const Cell &cell) const
    {
        return x == cell.x && y == cell.y;
    }

    bool operator <(const Cell &cell) const
    {
        if (x < cell.x)
        {
            return true;
        }
        return y < cell.y;
    }
};

std::ostream &operator<<(std::ostream &os, const Cell &cell)
{
    os << "{" << cell.x << "," << cell.y << "}";
    return os;
}

std::ostream &operator<<(std::ostream &os, const std::pair<int, Cell> &pair)
{
    os << "pair{" << pair.first << " {" << pair.second.x << "," << pair.second.y << "}}";
    return os;
}

namespace detail
{

template <std::size_t>
struct index_tag
{
    explicit constexpr index_tag() = default;
};

template <class T, class U>
constexpr T get_val_dispatch(std::pair<T, U> const& pair, index_tag<0>)
{
    return pair.first;
}

template <class T, class U>
constexpr U get_val_dispatch(std::pair<T, U> const& pair, index_tag<1>)
{
    return pair.second;
}

} // namespace detail

template <std::size_t N, class T, class U>
auto constexpr get_val(std::pair<T, U> const& pair)->
typename std::tuple_element<N, std::pair<T, U>>::type
{
    return detail::get_val_dispatch(pair, detail::index_tag<N> {});
}

int main()
{
    auto pair = std::make_pair(101, Cell(102, 103));

    std::cout << "pair1:        " << get_val<0>(pair) << " = " << get_val<1>(pair) << std::endl;
    using firstType = std::tuple_element<0, decltype(pair)>::type;
    using secondType = std::tuple_element<1, decltype(pair)>::type;
    std::cout << "firstType:    " << typeid(firstType).name() << std::endl;
    std::cout << "secondType:   " << typeid(secondType).name() << std::endl;

    return 0;
}

输出

pair1:        101 = {102,103}
firstType:    i
secondType:   4Cell

猜你喜欢

转载自blog.csdn.net/qq_40788199/article/details/135047727
今日推荐