从作为模板参数传递给构造函数的类继承,或者从它们继承

Inherit from classes passed to constructor as a template parameters an inherit from them

本文关键字:继承 或者 构造函数 参数传递      更新时间:2023-10-16

我想要这样的东西:

template<class... Args>
class MyClass : public Args
{
MyClass<class... Args>(/*some parameters*/)
{ }
}
// ana then:
MyClass<Base1, Base2, Base3>(/*some arguments*/)

我想dynamic_castBase1等等,并使用他的方法。

我知道这个代码不起作用,但你有什么想法吗?

这很好用:

struct Base1
{};
struct Base2
{};
struct Base3
{};
template<class... Args>
struct MyClass : public Args...
{};
MyClass<Base1, Base2, Base3> mc;

构造函数中不需要<>public Args之后缺少"…",类定义末尾缺少";"。

我知道这段代码不起作用,但你有什么想法吗?

要使其发挥作用,您必须进行

(1( 添加继承Args...的省略号(...(

class MyClass : public Args...
// ........................^^^

(2( 将MyClass设为struct或将public设为构造函数

(3( 删除定义构造函数的<class... Args>部分(它是隐式的(

(4( 添加一些如下

Args const & ... as

对于构造函数参数

(5( 添加分号以关闭类或结构

现在以下代码工作

struct Base1 {};
struct Base2 {};
struct Base3 {};
template<class... Args>
struct MyClass : public Args...
{
MyClass (Args const & ...)
{ }
};
int main()
{
MyClass<Base1, Base2, Base3>(Base1{}, Base2{}, Base3{});
MyClass(Base1{}, Base2{}, Base3{});  // C++17 only
}

观察main()中的最后一行

MyClass(Base1{}, Base2{}, Base3{});  // C++17 only

仅适用于C++17,因为使用了新的C++17:演绎指南。

在您的情况下,有一个隐式推导指南,允许从传递给构造函数的参数的类型推导类的模板类型。

另一个使用示例(更有用?(可能是

MyClass  mc{ Base1{}, Base2{}, Base3{} };

首先,您使用的是无效语法。当使用可变模板时,您需要在使用它们时"解压缩"它们(正确的术语:"扩展参数包"(:

template<typename... Args>
class MyClass : public Args ...
//                          ^^^
{ };

在构造函数中,您可以完全跳过模板参数,但如果您指定了它们,则需要再次"解压缩"它们:

MyClass<Args ...>(/*some parameters*/);
//     ^^^^^^^^^^   optional

一旦定义了类,就可以像使用经典模板一样指定模板参数,只是数字可能不同:

MyClass<Base1> c1;
MyClass<Base1, Base2> c2;
MyClass<Base1, Base2, Base3> c3;

由于C++17和适当的构造函数,您甚至可以让类模板参数得到推导:

template<typename... Args>
class MyClass : public Args ...
{
public:
MyClass(Args const&... args)
: Args(args)... // call base class copy constructors!
// (note the unpacking again)
{ }
MyClass(Args&&... args)
: Args(std::forward(args))... // call base class move constructors!
// (note the unpacking again)
{ }
};
MyClass c0;
MyClass c1(Base1());
MyClass C2(Base1(), Base2());
std::cout << std::is_same_v<decltype(c0), MyClass<>> << std::endl;
std::cout << std::is_same_v<decltype(c1), MyClass<Base1>> << std::endl;
std::cout << std::is_same_v<decltype(c2), MyClass<Base1, Base2>> << std::endl;

请注意,继承在这里只是转移注意力,没有继承也可以。请参见类模板参数推导。

让我按照您的要求向您展示一些工作示例:

#include<iostream>
class B1 {
private:
int *m;
public:
B1() { m = new int;}
~B1() { delete m;}
void SetM(int a) { *m = a;}
int GetM() { return *m;}
};
class B2 {
private:
std::string str;
public:
B2() { str = "";}
~B2() {}
void SetStr(std::string a) { str = a;}
std::string GetStr() { return str;}
};
class B3 {
private:
float f;
public:
B3() { f = 0.0 ;}
~B3() {}
void SetF(float a) { f = a;}
float GetF() { return f;}
};
template<class... Args>
class MyClass : public Args... {
};
int main () {
MyClass<B1,B2,B3> l;
l.SetM(1);
if (auto a = dynamic_cast<B1*>(&l)) {
std::cout<<" " << a->GetM() <<"n";
} else {
std::cout<<"ERROR:n";
}
}

希望这能有所帮助,谢谢,

Rajkumar