从子类中的不同属性列表中一般访问数据,同时保持多态行为

问题描述

通过使用常量表达式、参数包、lambda、移动语义、标准容器和 std::any,我可以轻松创建以下设计模式:

#include <utility>
#include <vector>
#include <any>

constexpr auto assign_properties = [](auto&&... t) { 
    return std::vector<std::any>{ std::move(t)... };  
};  

这将创建属性属性的任意列表,而无需定义 structclass 对象。

很简单,它可以按以下方式使用:

{
     auto props = assign_properties(1,3.1f,6.4,'a');
}

现在,要访问此容器中的类型安全数据,您必须事先知道每个元素的类型,并且必须以下列方式提取它们:

{
    auto a = std::any_cast<int>( props[0] );
    auto b = std::any_cast<float>( props[1] );
    auto c = std::any_cast<double>( props[2] );
    auto d = std::any_cast<char>( props[3] );
}

好的,这很简单也很公平...

假设我想在类层次结构中加入某种机制,例如这样的机制,以保留多态行为...

在类层次结构中,我可能想要一个所有类型都派生自的抽象基类型。对于每个派生类或子类,它们可能包含一组描述其行为或状态的属性属性,但是,每个子类可能具有不同数量的不同类型的属性...

例如:

class Animal {
protected:
    Animal(); // Abstract
    std::vector<std::any> attributes_;
};
     
class Cat : public Animal {  
public:
    // ...    
};

class Dog : public Animal {
public:
   // ...
};

class Eagle : public Animal {
public:
   // ...
};

现在,我没有在这里展示任何多态行为、虚拟方法或纯虚拟方法,因为它们对于我的问题的意图不是必需的,我将简要介绍......这些对象在其他一些代码中的其他地方正在创建然后填充...

struct Fur;    
struct Fangs;
struct Claws;
struct Feathers;
struct Talons;
struct Scales;

{
   Cat c1;
   c1.populate_attributes(assign_properties( "Fluffy",9,Fur,Fangs,Claws));

   Dog d1;
   d1.populate_attributes(assign_properties( "Ruff",3,Claws ));
   
   Eagle e1;
   e1.populate_attriutes(assign_properties( Fangs,Claws,Feathers,Talons );
}

足够简单...现在,正如我上面所说的,从 std::any 访问这些向量中的值需要您提前知道 type 以便使用 std::any_casttype-safe 方式提取其值。

假设我计划在解析文件时使用它来创建和填充我的类数据类型及其属性。然后在某个其他函数代码块中的其他地方,需要访问这些元素,而我不知道它们的类型是什么......此上下文中的 std::any 不提供任何设施,也不帮助我完成此过程。

{ 
    std::vector<Animals*> animals { Constructed & Populated; }
}
// some other code block
{
    auto a,b,c,d,...;
    a = animals[0];
    b = animals[1];
    c = animals[2];
    d = animals[3];
    
    // Above we got each individual animal from our external source vector...
    
    auto e,f,g,h,...;
    e = a[0]; // doesn't give the type and its value,e will be `std::any`.
    e = std::any_cast<auto>( e[0] ); // will fail to compile since `<T>` must
                                     // be kNown at compile time.
    e = std::any_cast<?>( e[0] );    // ... and this is where I'm stuck
                                     // I need some form of extraction here!
                                     // and I would like for it to be automatic and generic.
}        

如果用户提前不知道 types 并且需要在 type-safe 上下文中访问这些值,是否有一种简单的方法可以使用当前实现自动执行此检索或提取过程这是上面描述的?如果没有,可以做些什么来修改上面的代码以使其按预期工作,或者是否有任何其他机制或构造可以代替它来实现类似的设计模式,同时保留或提供我拥有的行为表达了吗?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)