C++;将未知类型传递给虚拟函数 我用C++编写,我想把一个未知类型(只知道在运行时)传递给纯虚函数: virtual void DoSomething(??? data);

C++;将未知类型传递给虚拟函数 我用C++编写,我想把一个未知类型(只知道在运行时)传递给纯虚函数: virtual void DoSomething(??? data);,c++,templates,virtual-functions,C++,Templates,Virtual Functions,其中,DoSomething是派生类中纯虚函数的实现 我计划使用模板,但事实证明,虚拟函数和模板无法协同工作: 我希望避免对传递给函数的所有类使用基类(类似于C#) 提前感谢您需要的。这方面的一个例子是通用(和C++17中的std::any) 然后,每个子类都可以尝试使用safe任何_cast,以获取它所需的数据 void DoSomething(boost::any const& data) { auto p = any_cast<std::string>(&d

其中,
DoSomething
是派生类中纯虚函数的实现

我计划使用模板,但事实证明,虚拟函数和模板无法协同工作:

我希望避免对传递给函数的所有类使用基类(类似于C#)

提前感谢

您需要的。这方面的一个例子是通用(和C++17中的
std::any

然后,每个子类都可以尝试使用safe
任何_cast
,以获取它所需的数据

void DoSomething(boost::any const& data) {
  auto p = any_cast<std::string>(&data);

  if(p) {
    // do something with the string pointer we extracted
  }
}
void DoSomething(boost::any const&data){
自动p=任意_转换(&data);
如果(p){
//对我们提取的字符串指针执行一些操作
}
}
当然,如果您寻求的行为范围更受限制,您可以推出自己的类型擦除抽象。

类似的东西?:

class Foo
{
    virtual ~Foo() = 0;
};

template <typename T>
class Bar : public Foo
{
    T object;
}

...

virtual void DoSomething(Foo* data)
{
    Bar<int>* temp = dynamic_cast<Bar<int>*>(data);
    if (temp)
         std::count<<temp->object;
}
class-Foo
{
虚拟~Foo()=0;
};
模板
分类栏:公共食品
{
T对象;
}
...
虚拟无效剂量测量(Foo*数据)
{
棒材*温度=动态铸件(数据);
如果(临时)

STD::Po.< p >如果您不想使用Booost/C++ 17,请考虑从基类派生“doMeTeNoT”函数的参数,并将动态CAST转换为正确的类对象。在这种情况下,您可以在运行时检查得到一个有效指针。

class param{
public:
    virtual ~param(){};
};

template <typename T>
struct specificParam:param{
    specificParam(T p):param(p){}
    T param;
};


class Foo
{
public:
    virtual void doSomething(param* data) = 0;
};

template <typename T>
class Bar : public Foo
{
public:
    virtual void doSomething(param* data){
        specificParam<T> *p = dynamic_cast<specificParam<T> *>(data);

        if (p != nullptr){
            std::cout<<"Bar got:" << p->param << "\n";
        }
        else {
            std::cout<<"Bar: parameter type error.\n";
        }
    }
};

int main(){
  Bar<char>   obj1;
  Bar<int>    obj2;
  Bar<float>  obj3;

  specificParam<char>   t1('a');
  specificParam<int>    t2(1);
  specificParam<float>  t3(2.2);

  obj1.doSomething(&t1); //Bar got:a
  obj2.doSomething(&t2); //Bar got:1
  obj3.doSomething(&t3); //Bar got:2.2

  // trying to access int object with float parameter
  obj2.doSomething(&t3); //Bar: parameter type error.
}
类参数{
公众:
虚拟~param(){};
};
模板
结构specificParam:param{
specificParam(tp):param(p){}
T参数;
};
福班
{
公众:
虚拟孔隙剂量测定(参数*数据)=0;
};
模板
分类栏:公共食品
{
公众:
虚拟无效剂量测量(参数*数据){
specificParam*p=动态_-cast(数据);
如果(p!=nullptr){

std::cout类型擦除不是唯一的可能性

您可能有兴趣使用visitor模式:将std::variant作为参数,并使用包含要实现的模板代码的lambda访问它:

virtual void doSomething(std::variant<int,float/*,...*/> data)
   {
   visit([=](auto v){/*...*/;},data);
   }
virtualvoiddosomething(标准::变量数据)
{
访问([=](自动v){/*…*/;},数据);
}

Foo
至少需要一个虚拟成员函数(可能是析构函数),否则
动态转换将无法工作。
我希望避免对传递给函数的所有类使用基类(类似于C中的object)这对于每个传递到函数中的对象不需要基类,只适用于包装器<代码> bar >代码>。虽然这在技术上是“传入对象”,但它不太可能是OP的意思。@ AZPopey从实用的角度考虑,在这种情况下,包装和派生是相同的机制,如<代码> DOOME。thing
必须向下转换接收到的对象;但我明白你的意思。你能说得更具体一点吗?你如何在函数中使用数据?类型对数据的要求是什么?例如,已知的类很少,或者你计划接受任何具有特定方法的类等?你的问题需要缩小一点。你知道吗你知道类型的范围,你想自动推断它们吗?最简单的答案是“使用void*”,更好的答案可能是Story Teller。这取决于您的用例。我很好奇,看看答案,是否有可能在不必对
doSomething
进行任何转换的情况下实现相同的结果。类似于以某种方式封装类型而不必制作
doSomething
模板e、 并使用
decltype
检索该类型,即一种虚拟工厂方法…发送未知类型参数有什么用?参数用于被使用,这看起来是一种错误的方法。使用动态多态性实现双重分派的常用方法是访问者模式
class Foo
{
public:
    virtual void doSomething(void* data) = 0;
};

template <typename T>
class Bar:public Foo
{
public:
    virtual void doSomething(void* data){
        T* pData = static_cast<T*>(data);
        std::cout<<"Bar1 got:" << *pData << "\n";
    }
};

int main(){

  Bar<char>  obj1;
  Bar<int>   obj2;
  Bar<float> obj3;

  char  c = 'a';
  int   i = 1;
  float f = 2.2;

  obj1.doSomething(&c); // Bar1 got:a
  obj2.doSomething(&i); // Bar1 got:1
  obj3.doSomething(&f); // Bar1 got:2.2

  //obj2.doSomething(&c); // Very bad!!!     
}
virtual void doSomething(std::variant<int,float/*,...*/> data)
   {
   visit([=](auto v){/*...*/;},data);
   }