C++ std::tie函数的作用和用法

电子说

1.3w人已加入

描述

函数原型

C++中std::tie函数的作用就是从元素引用中生成一个tuple元组,其在头文件中定义,其函数原型如下:

template< class... Types >
std::tuple< Types&... > tie( Types&... args ) noexcept; //C++11起, C++14前

template< class... Types >
constexpr std::tuple< Types&... > tie( Types&... args ) noexcept;//C++14起

其中参数 args 为构造 tuple 所用的零或更多左值参数。其返回值为含的std::tuple对象。

作用和用法

1. 解包 tuple 和 pair

std::tie 可以用于解包 tuple 和 pair,因为 std::tuple 拥有从 pair 的转换赋值。

注:元组tuple可以将不同类型的元素存放在一起,可以理解为pair的扩展(pair只能包含两个元素,而tuple可以多个)。

std::tuple拥有从 pair 的转换赋值的主要原因就是:tuple的实现中重载了 operator=,其部分原型如下:

template< class U1, class U2 >
tuple& operator=( const std::pair< U1, U2 >& p );//C++11 起, C++20 前

因此,std::tie可以用于pair的解包:

std::set< int > set;
std::set< int >::iterator iter;
bool result;
std::tie(iter, result) = set.insert(value);//解包 insert 的返回值为 iter 与 result
std::tie(std::ignore, result) = set.insert(value);//使用std::ignore忽略insert的返回pair中的第一个元素

:std::ignore 是令 std::tie 在解包 std::tuple 时作为不使用的参数的占位符使用,即忽略某些 tuple 中的某些返回值。

2. 批量赋值

std::tie 可以将多个变量的引用整合成一个 tuple,进而通过另外一个同类型的 tuple 进行批量赋值。

tuple< string, double, int > tup("idoit", 98.8, 1);
string name;
double score;
int rank;

//通过变量tup实现对name、score、rank的批量赋值操作
tie(name, score, rank) = tup;

3. 比较结构体

可以将结构体成员传入std::tie,从而实现结构体的比较。

struct S {
    int n;
    std::string s;
    float d;
    bool operator< (const S& rhs) const
    {
        // 比较 n 与 rhs.n,
        // 然后为 s 与 rhs.s,
        // 然后为 d 与 rhs.d
        return std::tie(n, s, d) < std::tie(rhs.n, rhs.s, rhs.d);
        //注:由于tie返回的是一个 tuple,tuple的实现已经重载了operator< ,因此可以利用tuple的operator< ,进而实现结构体S的operator< 。
    }
};

具体示例

#include < iostream >
#include < set >
#include < string >
#include < tuple >
using namespace std;

struct S {
    int n;
    string s;
    float d;
    bool operator< (const S& rhs) const {
        // 比较 n 与 rhs.n,
        // 然后为 s 与 rhs.s,
        // 然后为 d 与 rhs.d
        return tie(n, s, d) < tie(rhs.n, rhs.s, rhs.d);
    }
};

int main() {
    set< S > set_of_s;

    S value1{42, "Test1", 3.14};
    S value2{23, "Test2", 3.14};
    set< S >::iterator iter;
    bool result;

    /************解包**********/
    tie(iter, result) = set_of_s.insert(value1);
    if (result) cout < < "Value1 was inserted successfullyn";

    tie(std::ignore, result) = set_of_s.insert(
        value2);  // 使用std::ignore忽略insert的返回pair中的第一个元素
    if (result) cout < < "Value2 was inserted successfullyn";

    /***********结构体比较**********/
    bool r = value1 < value2;
    cout < < "value1 < value2 : " < < r < < endl;

    /***********批量赋值**********/
    tuple< string, double, int > tup("idoit", 98.8, 1);
    string name;
    double score;
    int rank;

    tie(name, score, rank) = tup;
    cout < < name < < " " < < score < < " " < < rank < < endl;

    return 0;
}

输出结果:

Value1 was inserted successfully
Value2 was inserted successfully
value1 < value2 : 0
idoit 98.8 1
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分