我试图在main.cpp中创建一个包含对象列表的简单对象管理器,我试图将" Target"进入列表,但是我收到一个错误:无法转换来自' Target *' to' int'。我不明白错误发生的原因?
另外,
之间的区别是什么manager.createObject<Target, 5>()
和
manager.createObject<Target>(5)
他们是一样的,即我正确地调用了这个函数吗?
// ObjectManager.h
class ObjectManager
{
std::vector<std::shared_ptr<Object>> objects; // list of all objects
public:
template<class T, typename... Args>
std::shared_ptr<T> createObject(Args&&... args) {
std::shared_ptr<T> new_ptr = std::make_shared<T>(new T(std::forward<Args>(args)...));
objects.emplace_back(new_ptr);
return new_ptr;
}
}
// Target.h
class Target
{
public:
int value;
Target(int _value) : value(_value) {}
};
// main.cpp
int main()
{
ObjectManager manager;
std::shared_ptr<Target> t = manager.createObject<Target>(5);
std::cout << t->value;
}
编辑:&#39;对象&#39; ObjectManager中的对象是我的实现代码的一部分,在这里不应该是这个例子的一部分 - 它应该只是Target
答案 0 :(得分:0)
您的代码中存在许多错误。我会从某个地方开始。
Object
课程。您未在此示例中包含它,或者您使用的是未定义的标识符。ObjectManager
类定义缺少;
Target
未从Object
延伸。您确定std::shared_ptr<Target>
可转换为std::shared_ptr<Object>
吗?我想不是。std::make_shared
。它不会将指针作为参数,而是您的类的构造函数参数。正确的用法是std::make_shared<T>(std::forward<Args>(args)...)
。正如错误所述,您的课程不能从Target*
构建,而是从int
构建。我可能没有发现其他问题。
现在,问题的第二部分。
您似乎在功能参数和模板参数之间存在混淆。两者都是不同的东西。
模板参数就像是函数实现的参数。有编译时实体。这就是你可以在那里发送类型的原因,因为类型是编译时实体。要有一个像这样可调用的函数:
foo<Bar, 5>();
你必须有这样的定义:
template<typename T, int n>
void foo() {}
正如函数定义所说,模板参数是一个类型和一个整数。您可以从调用函数的方式看出,您必须将模板参数作为模板参数发送。函数参数是(...)
中列出的参数。如果我们在函数中添加一些参数,它将如下所示:
template<typename T, int n>
void foo(const char*, int) {}
foo<Bar, 4>("baz", 7);
如您所见,功能参数和模板功能参数都是不同的,分开的东西。
模板参数推导是让编译器自己推导出模板参数是什么的过程。我不会进入整个过程,但它看起来像这样:
template<typename T>
void foo(T t) {}
foo(4); // deduce T as int
因此,您无需告知T
参数为int
。
我正确地调用了这个函数吗?
这确实是正确的方法:
manager.createObject<Target>(5)
它将使用模板参数T
作为Target
调用创建对象,并将... Args
推导为int
。没有int
模板参数,只有类型模板参数。