C++笔记 (可变参模版参数包展开)

本文深入探讨了C++中的折叠表达式概念,包括左折与右折运算,以及如何通过模板元编程实现参数包的处理。文章详细介绍了不同折叠表达式的使用场景,并展示了如何利用递归、类继承和组合方式来展开参数包,同时提供了tuple展开的实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/////////////////////////////////////////////////////////////////////////////
折叠表达式
左折:参数从左侧开始计算
右折:参数从右侧开始计算
template <typename ...T>
	auto add_val(T...arg)
	{
		return (... +  arg);//一元左折
	}
	template <typename...T>
	auto sub_val_left(T...arg)  //sub_val_left(10, 20, 30) -40  :((10-20)-30)
	{
		return (... - arg);
	}
	template <typename...T>
	auto sub_val_right(T...arg) 
		return (arg - ...);
	}

	template <typename...T>
	auto sub_val_left_b(T...arg)//二元左折 sub_val_left_b(10, 20, 30) :((220-10)-20)-30
	{
		return (220 - ... - arg);
	}
	template <typename...T>
	auto sub_val_right_b(T...arg) //sub_val_right_b(10, 20, 30) :(10-(20-(30-220)))
	{
		return (arg - ...-220);
	}

    template <typename...T>
    void pf(T const & ...args)
    {
        std::cout<<sub_val_right_b(2*args...)    //args = 10, 20, 30 : 2*10, 2*20, 2*30
    <<endl;
    }
/////////////////////////////////////////////////////////////////////////////////////
展开方式有:函数递归  类以继承的方式   组合方式  tuple

函数递归
////////////////////////////////////////
void end()
{
    std::cout<<"end"<<std::endl;
}
template<typename T, typename ...U>
void end(T arg, U...args)
{
    std::cout<<"arg"<<std::endl;
    end(args...);
    //if constexpr(!sizeof...(args) > 0) return ; 编译时求值c++17中
}
////////////////////////////////////////

类以继承的方式
////////////////////////////////////////
template<typename ...args>//泛化
class test
{
}
template<>
class test<>
{
public:
    test()
    {}

}
template<typename arg, typename ...args>//偏特化
class test<arg, args...>:private test<args...>
{
public:
    test(arg a, args... r):_i(a), test<args...>(r...)
    {
    }
    arg _i;
}
void pf()
{
	test<int, double, int, int> obj(10, 12.5, 20, 30);
}
////////////////////////////////////////
template<typename T, 
		template<typename U, typename = std::allocator<U>>typename...Container>
	class test_mm
	{
	public:
		test_mm()
		{
			std::cout << "test_mm() 泛化" << std::endl;
		}

	};

	template<typename T,
		template<typename U, typename = std::allocator<U>>typename var,
		template<typename U, typename = std::allocator<U>>typename...Container>
	class test_mm<T, var, Container...>:private test_mm<T, Container...>
	{
	public:
		test_mm()
		{
			std::cout << "test_mm() 特化" << std::endl;
			_con.push_back(12);
		}
		var<T> _con;
	};
	template<typename T,
		template<typename U, typename = std::allocator<U>>typename...Container>
	class test_mm_child :private test_mm<T, Container...>
	{
	public:
		test_mm_child()
		{
			std::cout << "test_mm_child() " << this<<typeid(T).name()//boost type_id_with_cvr<....>().pretty_name();
				<<sizeof...(Container)<< std::endl;

		}
	};

	void ptf()
	{
		test_mm_child<int, std::vector, std::list> obj;
	}
	
/////////////////////////////////////////


组合
////////////////////////////////////////
//组合方式展开地址不一样, 继承是一样的
	template<typename ...args>
	class test
	{
	public:
		test()
		{
			std::cout << "test()泛化" << std::endl;
		}
	};
	template<>
	class test<>
	{
	public:
		test()
		{
			std::cout << "test()特化" << std::endl;
		}
	};
	template<typename first, typename ...args>
	class test<first, args...> 
	{
	public:
		test() :_i(0)
		{
			std::cout << "test first" << std::endl;
		}
		test(first arg, args... _args) :_i(arg), _m_o(_args...)//, test<args...>(_args...)
		{
			std::cout << arg << "\t" << sizeof... (_args) << std::endl;
		}
		first _i;
		test<args...> _m_o;
	};
	void pf()
	{
		test<int, double, int, int> obj(10, 12.5, 20, 30);
	}
////////////////////////////////////////

tuple
/////////////////////////////////////////
template<int count, int maxcount, typename ...T>
	class test_c
	{
	public:
		static void func(const std::tuple<T...>& t)
		{
			std::cout << "value = " << std::get<count>(t) << std::endl;
			test_c<count + 1, maxcount, T...>::func(t);
		}
	};
	template<int maxcount,  typename ...T>
	class test_c<maxcount, maxcount, T...>
	{
	public:
		static void func(const std::tuple<T...>& t)
		{
			std::cout << "value = test_c" << std::endl;
		}
	};
	template<typename ...T>
	void test(const std::tuple<T...>& t)
	{
		test_c<0, sizeof...(T), T...>::func(t);
	}
	void pf()
	{
		std::tuple<float, int, int> obj(1.0f, 2, 3 );
		test(obj);
	}

/////////////////////////////////////////

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值