C++ 将 std::any 转换为基类,而不知道派生类类型

C++ cast std::any to base class without knowing derived class type

提问人:Gamaray 提问时间:4/15/2023 更新时间:4/15/2023 访问量:314

问:

这里有一个有点晦涩的问题,但我需要一种方法来转换为它的基类,而不知道它是什么派生类。std::any

换句话说,给定一个基类:

struct HCallable {
    int numArgs;
    std::vector<std::type_info> argTypes;
    virtual std::any call(std::vector<std::any> args)=0;
};

以及其(众多)派生类之一的实例:

class in : public HCallable {
public:
int numArgs=1;

std::any call(std::vector<std::any> args) {
    std::cout << huff::anyToString(args[0]);
    std::string result;
    std::getline(std::cin, result);
    return result;
}
};

std::any instance = std::any(new in()); 

我怎样才能接受这个实例,并在不知道有类型的情况下将其转换为类型的对象。HCallableinstancein

如果只有我能找到一种不明确声明的方法,此代码就可以工作:in*

HCallable* func =  dynamic_cast<HCallable*>(std::any_cast<in*>(instance));
C++ 转换 多态性 stdany

评论

0赞 HolyBlackCat 4/15/2023
你控制基类吗?我有一个技巧,但它需要向每个需要用作强制转换目标的基类添加某个宏。
2赞 fabian 4/15/2023
为什么不让虚拟的析构函数和???一起去顺便说一句:由于您的问题似乎与 的签名完全无关,我建议从该签名中删除;这样可以更容易地确定您实际询问的用途......HCallablestd::unique_ptr<HCallable> instance = std::make_unique<in>();callstd::anystd::any
0赞 Aykhan Hagverdili 4/15/2023
相关?
0赞 user17732522 4/15/2023
"我怎样才能获取这个实例,并在不知道该实例有类型的情况下将其转换为 HCallable 类型的对象。的重点是存储不通过继承相关的任意(可复制)类型。如果包含的类型甚至没有继承自,会发生什么?在不知道包含的类型的情况下,唯一允许你做的就是复制它。对于存储与继承相关的类型,您可能应该使用或或它的某些自定义变体,具体取决于确切的用例。std::anyHCallablestd::anystd::unique_ptr<HCallable>std::function
0赞 user17732522 4/15/2023
一般来说,(以及 )只是很少有用。如果你发现自己经常使用它,那么你的一般方法可能是有问题的。特别是,我不认为正如你所定义的那样,这是一个好主意。它打算如何使用?std::anystd::type_infoHCallable

答:

-2赞 Deepak Kumar 4/15/2023 #1

下面介绍如何使用 和 将未知派生类的对象转换为其基类类型std::any_castdynamic_cast.

首先,您需要从 std::any 中提取指向派生类对象的存储指针。为此,可以使用指向基类的指针,然后可以使用 dynamic_cast安全地将指针转换为基类指针类型。std::any_castHCallableHCallable*

下面是您可以执行以下操作的示例:

std::any instance = std::make_any<DerivedClass>();

// Extract derived class object from std::any
auto derivedPtr = std::any_cast<DerivedClass*>(&instance);

// convert the pointer to the base class
HCallable* basePtr = dynamic_cast<HCallable*>(*derivedPtr);

// Check if pointer conversion completed before using basePtr
if (basePtr) {
    // Here you can use basePtr as an HCallable*
} else {
    // error
}

评论

0赞 chrysante 4/15/2023
这正是OP想要避免的。他们想在不知道派生的类型的情况下强制转换为基数。