C++ 17/20/23可变参数模板类继承使用示例(低于c++17可参考)

#include <iostream>

// 测试类
class BaseA
{
public:
	void print(int v){ std::cout << __FUNCTION__ << " value : " << v << std::endl; }
};

class BaseB
{
public:
	void print(const std::string_view str){ std::cout << __FUNCTION__ << " value : " << str << std::endl; }
};


class BaseC
{
public:
	BaseC(int a = 1, double d = 1.1, std::string str = "")
	{
		std::cout << "a: " << a << " d: " << d << " str: " << str << std::endl;
	}
	~BaseC() {}
public:
	void print(double d) { std::cout << __FUNCTION__ << " value : " << d << std::endl; }
};

/************************************************VariableTypeClass_A 可变数量类继承模板***********************************************************/

// 未提供构造函数 通过模板实例化或{}进行构造对象
template<typename... Args>
class VariableTypeClass_A: public Args...
{
public:
	// 如果继承了Args类,并且类中的函数print是重载关系。
		// 需要通过using进行声明. 如果继承的基类中函数相同,并且都用了using声明,则会报歧义错。
	using Args::print...;
};

// 未提供构造函数 类外提供推倒方式 进行声明,达到根据参数个数,确定类型个数并实例化类。
template<typename... Args>
class VariableTypeClass_B : public Args...
{
public:
	// 如果继承了Args类,并且类中的函数print是重载关系。
		// 需要通过using进行声明. 如果继承的基类中函数相同,并且都用了using声明,则会报歧义错。
	using Args::print...;
};

template<typename...Args>
VariableTypeClass_B(Args...)->VariableTypeClass_B<Args...>;


// 提供构造函数
template<typename... Args>
class VariableTypeClass_C : public Args...
{
public:
	// 通过 {}... 或 ()... 推断类型实例化基类
	VariableTypeClass_C(const Args&... args) : Args{ args }... {}
	//VariableTypeClass_C(const Args&... args) : Args(args)...{}

public:
	// 如果继承了Args类,并且类中的函数print是重载关系。
		// 需要通过using进行声明. 如果继承的基类中函数相同,并且都用了using声明,则会报歧义错。
	using Args::print...;
};

// 为继承的每个类,提供不同参数的构造函数(可变参数构造函数). 需要类外提供推倒方式 进行声明
template<typename... Args>
class VariableTypeClass_D : public Args...
{
public:
	template<typename... Ts>
	VariableTypeClass_D(Ts&&... args) : Args( std::forward<Ts>(args))...{}

public:
	// 如果继承了Args类,并且类中的函数print是重载关系。
		// 需要通过using进行声明. 如果继承的基类中函数相同,并且都用了using声明,则会报歧义错。
	using Args::print...;
};

template <class ...Args>
VariableTypeClass_D(Args&&...)->VariableTypeClass_D<std::remove_reference_t<Args>...>;


/// test function
void test_VariableTypeClass_A();
void test_VariableTypeClass_B();
void test_VariableTypeClass_C();
void test_VariableTypeClass_D();

/*************
 * 总结: 如果在实例化类对象时,不通过<>显示对象实例化。通过参数隐式类型推导要继承的类型。
 *		① 必须在类中提供非模板 构造函数如 test_VariableTypeClass_C
 *		② 在实例化对象时通过{}方式进行实例化如 test_VariableTypeClass_A
 *		③ 在类外 提供可变参数声明 template<typename...Args> VariableTypeClass_B(Args...)->VariableTypeClass_B<Args...>; 如 test_VariableTypeClass_B
 *		注意: 如果构造函数为模板构造函数,同样需要提供 可变参推倒声明。如 test_VariableTypeClass_D
 *			  仅适用通过参数推导类型。因为提供了拷贝构造方式构造基类,所以要有对象。
 ************/

/// 附 继承一种类型,但该类型的参数可变

// 继承类可变参构造(针对不同类的构造函数不同)
template<typename T>
class VariableConstructor_A : public T
{
public:
	template<typename... Args>
	VariableConstructor_A(Args... args):T(args...) {}
};

template<typename T>
class VariableConstructor_B : public T
{
public:
	template<typename... Args>
	VariableConstructor_B(Args&&... args) :T(std::forward<Args>(args)...) {}

public:
	using T::print;
};

void test_VariableConstructor()
{
	VariableConstructor_B<BaseC> c(1,1.1,"ssss");

	c.print(1.1);
}



int main()
{
	//test_VariableTypeClass_A();
	//test_VariableTypeClass_B();
	//test_VariableTypeClass_C();
	//test_VariableTypeClass_D();
	test_VariableConstructor();

	return 0;
}

void test_VariableTypeClass_D()
{
	BaseA a;
	BaseB b;
	VariableTypeClass_D vatd_1(a,b);
	vatd_1.print("VariableTypeClass_D");


}

void test_VariableTypeClass_C()
{
	BaseA a;
	BaseB b;
	VariableTypeClass_C vatc_1(a,b);
	vatc_1.print("VariableTypeClass_C");
}

void test_VariableTypeClass_B()
{
	BaseA a;
	BaseB b;
	VariableTypeClass_B vtb_1(a,b);
	vtb_1.print("类外提供推到方式..");
}

void test_VariableTypeClass_A()
{
	// 使用方式 1 通过模板<>实例化
	VariableTypeClass_A<BaseA, BaseB>	vta_1;
	vta_1.print("hello world.");

	// 使用方式 2 如果VariableTypeClass_A类中没有提供构造函数,通过 {基类对象A,基类对象B...} 方式进行类型推断构造
	BaseA a;
	BaseB b;
	VariableTypeClass_A vta_2{ a,b };
	vta_2.print("2");
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_虚竹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值