在 C++ 中,如果
目前,我遇到了一个情况,我想通过
我知道通过
但也许有一些变通方法或者聪明的技巧可以使用?感觉这样必须是可以实现的,因为在 C++ 中向上转型是如此普遍,而
下面是一个代码示例。以下代码会崩溃,因为在
Base
是 Derived
的基类,则可以将 Derived
的实例传递给接受 Base
的函数。这对于满足 API 和 API 的常见设计模式非常有用。目前,我遇到了一个情况,我想通过
std::any
进行向上转型。也就是说,我有一个存储 Derived
实例的 std::any
,我希望在一个不知道 Derived
存在的 API 函数中将其地址转换为指向 Base
的指针。我的用例是一个运行时反射库,它传递存储反射类型实例的 std::any
。我知道通过
std::any
进行向上转型是不可能的,因为 std::any_cast
在转换之前会检查类型,如果类型不匹配,则返回 nullptr
,详情请参见 cppreference。但也许有一些变通方法或者聪明的技巧可以使用?感觉这样必须是可以实现的,因为在 C++ 中向上转型是如此普遍,而
std::any
确实 有我需要的地址和类型。下面是一个代码示例。以下代码会崩溃,因为在
any_function
中,std::any_cast
返回了 nullptr
,而在下一行中对其进行了解引用。编译器资源管理器:https://godbolt.org/z/E9sG9G3ff
#include <any>
#include <iostream>
class Base
{
public:
double get_val() const {
return val;
}
private:
double val {1.23};
};
void normal_function(Base const& b){
std::cout << b.get_val() << std::endl;
};
void any_function(std::any const& b){
auto* ptr = std::any_cast<Base>(&b);
std::cout << ptr->get_val() << std::endl;
}
class Derived : public Base {};
int main()
{
Derived d;
// normal upcasting
normal_function(d);
// upcasting thru std::any
std::any ad = d;
any_function(ad);
return 0;
}
Derived*
向Base*
进行强制转换可能需要指针算术运算,这取决于Base
在Derived
布局中的位置。因此,在进行转换时,必须意识到两种类型。对于“普通”类之间的多态性,它可以工作,因为调用方知道需要进行强制转换,但是对于std::any
来说,不存在这样的机制。你是否必须使用std::any
,还是可以使用其他类型? - lorrostd::any
。它经常被用作一个逃避方式,一个快速而肮脏的黑客,而不是实现一个完全类型安全的代码。也许有一个更合适的解决方案,可以避免使用std::any
。 - Sam Varshavchikstd::any
而不是类似于void *
的东西...但也许std::any
太过限制性,我必须想出自己的非STL any-like容器类。 - joergbrechvoid*
也无法实现您尝试的操作。您不能将Derived*
转换为void*
,然后再将其转换为Base*
。 - Nicol Bolasstd::any
几乎从来不是解决任何问题的方案。在大多数情况下,当你想要“任意类型”时,你真正需要的是std::variant
。如果std::variant
不符合你的需求,那么你设计的东西就有问题,需要重新开始。 - Mooing Duck