从 类 继承作为模板参数传递给构造函数并从它们继承

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

我想要这样的东西:

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 后缺少“...”并且缺少“;”在 class 定义的末尾。

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

#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";
}

}

希望这对您有所帮助, 谢谢,

拉库玛

I know that this code will not work, but do you have any ideas how to do it?

要让它发挥作用,您必须

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

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

(2) 使 MyClass 成为 struct 或使 public 成为构造函数

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

(4) 增加一些如下

   Args const & ... as

对于构造函数参数

(5) 添加分号结束 class 或 struct

现在下面的代码可以工作了

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:演绎指南。

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

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

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

一开始,您使用的语法无效。使用可变参数模板时,需要'unpack'它们(正确的术语:'expand the parameter pack')使用它们时:

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

在构造函数中,您可以完全跳过模板参数,但是如果您指定它们,您需要再次'unpack'它们:

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

定义 class 后,您可以像使用 classic 模板一样指定模板参数,唯一不同的是数字:

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

从 C++17 开始,使用适当的构造函数,您甚至可以推导 class 模板参数:

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;

请注意,继承在这里是一个转移注意力的问题,没有继承也可以。参见 class template argument deduction