0

通过使用常量表达式、参数包、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, Fur, Fangs, Claws ));
   
   Eagle e1;
   e1.populate_attriutes(assign_properties( Fangs, Claws, Feathers, Talons );
}

很简单......现在,正如我上面所说,访问这些向量中的值std::any需要你type提前知道,以便以某种方式std::any_cast提取它的值。type-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上下文中访问这些值,是否有一种简单的方法可以使用上述当前实现自动执行此检索或提取过程?如果没有,可以做些什么来修改上述代码以使其按预期工作,或者是否有任何其他机制或构造可以用来代替它来实现类似的设计模式,同时保留或提供我拥有的行为表达?

4

0 回答 0