我正在尝试构建一个注入(inject)类,该类允许以某个名称注入(inject)任何其他类,以便自动将所述注入(inject)类传递给注入(inject)类的构造函数。这样做的原因是因为注入(inject)类包含一些设置我想要管理的注入(inject)类所需的变量。
目前我有一些这样的代码:
#include <memory>
#include <string>
#include <stdout>
#include <typeindex>
class Injector {
private:
std::map<std::type_index, std::map<std::string, std::shared_ptr<void>>> instances;
public:
template<class T, typename... Args>
void inject(std::string name, Args&&... args) {
static_assert(std::is_constructible_v<T, Args..., Injector*>, "Cannot construct type with given args");
auto resourcePtr = std::make_shared<T>(std::forward<Args>(args)..., this);
instances[typeid(T)][name] = resourcePtr;
}
template<class T>
T get(std::string name) {
auto nameToTMap = instances.find(typeid(T));
if (nameToTMap == instances.end()) {
return std::nullopt;
}
auto mapInstance = nameToTMap->second;
auto instance = mapInstance.find(name);
if (instance == mapInstance.end()) {
return std::nullopt;
}
// Here is my problem
auto typedInstance = std::dynamic_pointer_cast<T>(instance->second);
if (!typedInstance) {
return std::nullopt;
}
return typedInstance;
}
};
class Foo {
public:
Foo(int x, int y, Injector injector) {
printf("Hello from Foo, %i, %i", x, y);
}
}
int main() {
Injector injector;
injector.inject<Foo>("foo", 1, 2); // Prints "Hello from Foo, 1, 2"
std::shared_ptr<Foo> myFoo = injector.get<Foo>("foo");
return 0;
}
编译(clang++)时出现错误:
error: 'void' is not a class type
_ET* __p = dynamic_cast<_ET*>(__r.get());
^ ~~~~~~~~~
note: in instantiation of function template specialization 'std::__1::dynamic_pointer_cast<Foo, void>' requested here
auto typedInstance = std::dynamic_pointer_cast<T>(instance->second);
我尝试了几种不同的东西(比如有一个 Injectable
类)但没有任何效果,所以我想知道这样的东西在 C++ 中是否也有效?我从shared_ptr<void>
知道选角至shared_ptr<T>
总是会得到正确的结果,因为 void
ptr 存储在 map
中在T
键下
如果这不起作用,是否有其他方法可以以可靠的方式自动将变量传递给实例化/函数调用?
最佳答案
.get()
不属于那里。 std::dynamic_pointer_cast
适用于shared_ptr
直接,而不是原始指针。
另外,您想要 std::static_pointer_cast
反而。这相当于 static_cast
如果您要使用原始指针而不是 std::shared_ptr
,这是正确的选择。 dynamic_cast
在指向多态类层次结构中不同(子)对象的指针之间进行转换。 static_cast
类型转换 void*
到任何其他指针类型,而不影响指针指向哪个对象(假设指针的地址与 T
适当对齐)。
您有责任确保 std::shared_ptr<void>
实际上指向 T
类型的对象。否则使用 std::static_pointer_cast<T>
进行强制转换当使用结果指针时,将(极少数异常(exception))导致未定义的行为。
特别是if (!typedInstance)
对于 Actor 阵容没有做任何有用的事情。仅当原始 std::shared_ptr<void>
时它才会失败本来就已经空了。如果std::shared_ptr<void>
不指向 T
类型的对象,那么强制转换的结果仍然不是(保证是)空指针。
关于c++ - 如何将shared_ptr<void>转换为另一种类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75762735/