模板对象管理器,参数不正确

时间:2017-07-26 23:16:03

标签: c++ templates pointers

我试图在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

1 个答案:

答案 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模板参数,只有类型模板参数。