2_9_3 boost库、模板类型参数类型推断、auto类型推断、decltype类型推断

9_3_boost_类型推断.cpp

#include "hjcommon.hpp"
#include "boost/type_index.hpp"

template<typename T, typename Q>
static void aFunc(T &tvar, const Q &qvar) // 把引用换乘指针,行为是一样的
{
	using boost::typeindex::type_id_with_cvr; // 使用 type_id_with_cvr ,可以得到数据类型或变量的数据类型名称
	std::string TName = ((boost::typeindex::type_index)type_id_with_cvr<T>()).pretty_name();
	std::string QName = ((boost::typeindex::type_index)type_id_with_cvr<Q>()).pretty_name();
	std::string tvarName = ((boost::typeindex::type_index)type_id_with_cvr<decltype(tvar)>()).pretty_name();
	std::string qvarName = ((boost::typeindex::type_index)type_id_with_cvr<decltype(qvar)>()).pretty_name();
	cout << "T=" << TName << ", tvar=" << tvarName << ", Q=" << QName << ", qvar=" << qvarName << endl;
}
template<typename T>
static void bFunc(T &tvar1, const T &tvar2) // 这种情况,当形参既有 T& 又有 const T&, T只会被推断为 int ,所以若实参为 const 类型时,编译器会报错
{
	using boost::typeindex::type_id_with_cvr; // 使用 type_id_with_cvr ,可以得到数据类型或变量的数据类型名称
	std::string TName = ((boost::typeindex::type_index)type_id_with_cvr<T>()).pretty_name();
	std::string tvar1Name = ((boost::typeindex::type_index)type_id_with_cvr<decltype(tvar1)>()).pretty_name();
	std::string tvar2Name = ((boost::typeindex::type_index)type_id_with_cvr<decltype(tvar2)>()).pretty_name();
	cout << "T=" << TName << ", tvar1=" << tvar1Name << ", tvar2=" << tvar2Name << endl;
}
template<typename T>
static void cFunc(T &&tvar) // 万能引用
{
	using boost::typeindex::type_id_with_cvr; // 使用 type_id_with_cvr ,可以得到数据类型或变量的数据类型名称
	std::string TName = ((boost::typeindex::type_index)type_id_with_cvr<T>()).pretty_name();
	std::string tvarName = ((boost::typeindex::type_index)type_id_with_cvr<decltype(tvar)>()).pretty_name();
	cout << "T=" << TName << ", tvar=" << tvarName << endl;
}
template<typename T>
static void dFunc(T tvar) // 传值方式
{
	using boost::typeindex::type_id_with_cvr; // 使用 type_id_with_cvr ,可以得到数据类型或变量的数据类型名称
	std::string TName = ((boost::typeindex::type_index)type_id_with_cvr<T>()).pretty_name();
	std::string tvarName = ((boost::typeindex::type_index)type_id_with_cvr<decltype(tvar)>()).pretty_name();
	cout << "T=" << TName << ", tvar=" << tvarName << endl;
}
template<typename T>
static void eFunc(T &tvar) // 数组
{
	using boost::typeindex::type_id_with_cvr; // 使用 type_id_with_cvr ,可以得到数据类型或变量的数据类型名称
	std::string TName = ((boost::typeindex::type_index)type_id_with_cvr<T>()).pretty_name();
	std::string tvarName = ((boost::typeindex::type_index)type_id_with_cvr<decltype(tvar)>()).pretty_name();
	cout << "T=" << TName << ", tvar=" << tvarName << endl;
}
template<typename T, unsigned len>
static void eeFunc(T (&tvar)[len]) // 数组
{
	using boost::typeindex::type_id_with_cvr; // 使用 type_id_with_cvr ,可以得到数据类型或变量的数据类型名称
	std::string TName = ((boost::typeindex::type_index)type_id_with_cvr<T>()).pretty_name();
	std::string tvarName = ((boost::typeindex::type_index)type_id_with_cvr<decltype(tvar)>()).pretty_name();
	cout << "T=" << TName << ", tvar=" << tvarName << ", len=" << len << endl;
}
static void test() {}
template<typename T>
static void fFunc(T tvar) // 函数名作实参
{
	using boost::typeindex::type_id_with_cvr; // 使用 type_id_with_cvr ,可以得到数据类型或变量的数据类型名称
	std::string TName = ((boost::typeindex::type_index)type_id_with_cvr<T>()).pretty_name();
	std::string tvarName = ((boost::typeindex::type_index)type_id_with_cvr<decltype(tvar)>()).pretty_name();
	cout << "T=" << TName << ", tvar=" << tvarName << endl;
}
template<typename T>
static void gFunc(T &tvar) // 函数名作实参
{
	using boost::typeindex::type_id_with_cvr; // 使用 type_id_with_cvr ,可以得到数据类型或变量的数据类型名称
	std::string TName = ((boost::typeindex::type_index)type_id_with_cvr<T>()).pretty_name();
	std::string tvarName = ((boost::typeindex::type_index)type_id_with_cvr<decltype(tvar)>()).pretty_name();
	cout << "T=" << TName << ", tvar=" << tvarName << endl;
}

int main_2_9_3(int argc, char *argv[])
{
	// boost库:开源,比较悠久
	// boost库下载:https://www.boost.org 解压目录:/usr/local/cpp/boost_1_69_0
		// cd /usr/local/cpp/boost_1_69_0
		// sudo ./bootstrap.sh --prefix=/usr/local/cpp/boost
		// sudo ./b2 install   // 编译需要很久.
			// 最后会在 /usr/local/cpp/boost/ 下生成 include 与 lib 目录
				// 将 /usr/local/cpp/boost/include 添加进eclipse环境变量, 记得还要在 CMakeList.txt 中include该路径,否则编译时会找不到, 链接不需要指定so库?
					// eclipse的环境变量有点问题。。 我直接将 /usr/local/cpp/boost/include/boost 头文件目录复制到了 /usr/local/include 下了。
	int a = 0; long aa = 0;
	const int b = a; const long bb = aa;
	const int &c = 1; const long &cc = 1;
	int &&d = 1; long &&dd = 1;
	const int &&e = 1; const long &&ee = 1;
	cout << "------------------引用与指针---------------------" << endl;
	aFunc(a, aa); // T=int, tvar=int&, Q=long, qvar=long const&
	aFunc(b, bb); // T=int const, tvar=int const&, Q=long, qvar=long const&
	aFunc(c, cc); // T=int const, tvar=int const&, Q=long, qvar=long const&
	aFunc(d, dd); // T=int, tvar=int&, Q=long, qvar=long const&
	aFunc(e, ee); // T=int const, tvar=int const&, Q=long, qvar=long const&

	cout << "-------------------T& 且 const T&--------------------" << endl;
	bFunc(a, a); // 可以
//	bFunc(b, b);  // 这种情况,当形参既有 T& 又有 const T&, T只会被推断为 int ,所以若给实参 T& 传 const 类型时,编译器会报错
//	bFunc(c, c); // 不可以
	bFunc(d, d); // 可以
//	bFunc(e, e); // 不可以

	cout << "------------------万能引用---------------------" << endl;
	cFunc(a); // T=int&, tvar=int&
	cFunc(b); // T=int const&, tvar=int const&
	cFunc(c); // T=int const&, tvar=int const&
	cFunc(d); // T=int&, tvar=int&
	cFunc(e); // T=int const&, tvar=int const&			// 虽然 d与e 是右值,但是当使用 d与e 时,却是被当作左值来使用的。
	cFunc(7); // T=int, tvar=int&&

	cout << "------------------传值方式 T t ---------------------" << endl;
	dFunc(a); // T=int, tvar=int
	dFunc(b); // T=int, tvar=int			// const 属性没有传递进去,也就是函数模板中,参数可以修改
	dFunc(c); // T=int, tvar=int
	dFunc(d); // T=int, tvar=int
	dFunc(e); // T=int, tvar=int
	char f[] = "some";
	const char *g = f;
	const char *const h = g;
	const char i[] = "hi";
	dFunc(f); // T=char *, tvar=char *
	dFunc(g); // T=char const*, tvar=char const*		// 当实参为常指针时,const属性能传递进去一部分
	dFunc(h); // T=char const*, tvar=char const*
	dFunc(i); // T=char const*, tvar=char const*

	cout << "------------------数组---------------------" << endl;
	eFunc(i); // T=char const [3], tvar=char const (&) [3]
	eeFunc(i); // T=char const, tvar=char const (&) [3], len=3      // 数组引用

	cout << "------------------函数名作实参---------------------" << endl;
	fFunc(test); // T=void (*)(), tvar=void (*)()    // 函数指针
	gFunc(test); // T=void (), tvar=void (&)()		 // 函数类型引用

	return 0;
}

9_5_auto.cpp

#include "hjcommon.hpp"
#include "boost/type_index.hpp"

template<typename T>
static void aFunc(T &tvar)
{
	using boost::typeindex::type_id_with_cvr; // 使用 type_id_with_cvr ,可以得到数据类型或变量的数据类型名称
	std::string TName = ((boost::typeindex::type_index)type_id_with_cvr<T>()).pretty_name();
	std::string tvarName = ((boost::typeindex::type_index)type_id_with_cvr<decltype(tvar)>()).pretty_name();
	cout << "T=" << TName << ", tvar=" << tvarName << endl;
}

static auto abc() { return 0; } // c++14,auto可作为函数返回值类型

class A
{
public:
	static const auto m_num = 0; // auto可作为静态成员变量,且必须是const,可以而且必须在类内初始化。。
};

int main_2_9_5()
{
	// auto : auto有类型,auto的变量也有类型,类似于模板类型参数 T
	auto a = 1; // 可以,int
	const auto b = 1;  // 可以,const int
	const auto &c = a; // 可以,const int&
	const auto &d = 1; // 可以,const int&
	auto &&e = 1; // 可以,int&&
//	const auto &&f = a; // 不可以,const右值引用,不能用左值赋
	const auto &&g = 1; // 可以,cosnt int&&

	auto &h = c; // cosnt int& ,auto会丢弃引用属性(引用折叠了),但不会丢弃const属性
	auto hh = b; // int,同模板参数传值方式一样

	auto i { 30 }; // int
	auto j = { 30 }; // std::initializer_list<int> c++11新数据类型,类模板,表示特定值的数组
	std::string tName = ((boost::typeindex::type_index)boost::typeindex::type_id_with_cvr<decltype(j)>()).pretty_name();
	cout << "tName=" << tName << endl;
	// auto 不能作为函数形参、不能作为非静态成员变量

	return 0;
}

9_6_decltype.cpp

#include "hjcommon.hpp"
#include "boost/type_index.hpp"

class A
{
public:
	int i;
};

static int func()
{
	cout << "func." << endl;
	return 0;
}

int main_2_9_6()
{
	// decltype() c++11,返回操作数的数据类型,同auto一样,编译期间推断。 decltype能保留引用符 & ,decltype类型推导几乎是原封不动的推导出操作数的数据类型
	// decltype 操作数是变量   decltype() 可以声明变量。。
	const int a = 0;
	const int &b = a;
	decltype(a) c = a; // c = const int
	decltype(b) d = a; // d = const int &
	decltype(A::i) e; // int
	A aa;
	decltype(aa.i) f; // int
	auto &&g = a; // int &
	decltype(g) &&h = a; // int & ,引用折叠了

	// decltype 操作数是被表达式
	decltype(2) i = 0; // int
	int j = 0;
	int *pj = &j;
	decltype(*pj) k = i; // int &
	decltype(j) l = j; // int
	decltype( (j) ) m = j; // int & 。。
	int mm = 0;
	decltype(std::move(mm)) dm = 1; // int&& ,按道理 std::move(mm) 也不会真执行。

	// decltype 操作数是函数
	decltype(func()) n = 0; // int ,并不会调用func()函数。 同理 A() 也不会生成 A() 临时对象
	decltype(func) *o = func; // int (void)
	o();

	// decltype 抽取操作数变量类型
	vector<int> vec;
	decltype(vec)::size_type size = vec.size();

	// decltype 用于后置返回函数

	// decltype(auto) c++14 ,可用于前置返回函数,推导 auto 的数据类型
	const int &p = 0;
	decltype(auto) r = p; // const int &

	std::string tName = ((boost::typeindex::type_index)boost::typeindex::type_id_with_cvr<decltype(dm)>()).pretty_name();
	cout << "tName=" << tName << endl;

	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值