当前位置: 首页 > 工具软件 > tie > 使用案例 >

C++_tuple, tie, std::get<>

慕容博涛
2023-12-01

::std::get<>

要么返回的是: &引用, 要么返回的是: const &常量引用;

即, std::get< 0>( t), 他返回的, 一定是 t这个tuple的 第一个元素的 引用, 不会产生 (临时对象)!!!

至于是不是const 引用, 自然取决于: t对象本身, 是不是const

tuple源码

template <typename Head , typename... Tail>
class tuple<Head, Tail> : private tuple<Tail...>{
protected:
    Head m_head;  
public:
	tuple(Head h , Tail... t) : m_head(h), tuple<Tail...>(t){} 
};

template <>
class tuple<>{};

即,tuple是会存数据的
int a,b; tuple<int&, int&> tu(a, b); 此时,tu里存的,都是引用
&get<0>(tu) == &a

tie

template< class... Types >
std::tuple<Types&...> tie( Types&... args ) noexcept;

tie会返回一个tuple对象!!!
tie的函数参数,都是引用!!所以,参数一定都是变量,不可以是常量。

int a, b;
tuple<int&, int&> tie<int, int>(a, b);

仔细理解!!!
tie的模板参数<int>,他只是表示 tie的函数参数 的“type”,并不代表方式!!
具体函数参数是 值传递 还是 引用传递 还是 指针传递,这不是 模板参数负责的。要看函数参数定义

而tie函数参数是: (T&),即是以引用方式传递的。

返回值是tuple<T&> 表示: 返回值是一个tuple,且tuple里每个数据 都是引用。

比如:

template <typename T>
T& func(T& t){ 
	return t;
}

int a = 123;
int& ref = a;
int& ref = func<int>(a); 

因为,引用和值 可以直接赋值: int& a = b; a = 123;(a是&引用,123是值)
tuple<int&, int&> = tuple<int,int>(1, 2);这是可行的!!

这是tie的核心。

tuple<char, int, double> tu('a', 123, 3.333);

char a; int b; double c;

如果我们要得到tu里的每个变量 另存到abc里。
'a = get<0>(tu) 这是一种方式。 但是,你得一个个的写,比较麻烦。'

tie(a, b, c) = tu; ' 这一句话,就等于上面的3句话 '
他的本质是:
tuple<char&, int&, double&> temp = tie(a, b, c);
temp = tu; ' temp里,每个引用的值,就等于 tu里每个值 '
你写成: 'tie(a, b, c) = tu',其实是有temp这个tuple类型的对象!!
只不过,你不需要使用它。 过了局部域,这个匿名对象,就会销毁

你原先tu里的a, 123, 3.333这些变量a,b,c这些变量,只是值相同。内存肯定不同…


tie对pair:

pair<int, int> p(1,2);

int a, b;
tie(a, b) = p;

其实他的实现原理是:

  • tuple有一个pair的构造函数!! 即tuple<int,int> tu( pair<int,int>& )
    = p,其实是: = (tuple<int,int>)p;

这就和上面的tie一样的,即把一个tuple 解开到每个值。

总之,记住核心的一点: tie就是返回一个“tuple”,这个tuple内部存的变量 都是引用
只不过,我们一般使用时, 我们都把他当成“匿名变量”来使用。但其实他就是一个tuple类型的对象

用处—简化比较

class ST{
	char a;
	int b;
	
	bool operator==(const ST & _t){
		return tie(a, b) == tie(_t.a, _t.b);
	}
};

因为tuple里,已经实现了==, <, >等,你可以直接用tuple的比较规则。 否则,你需要自己再手写。

 类似资料: