我有这个集合:
vector<unique_ptr<Light>>* lights;
我有很多Light
类的后代,比如DirectionalLight
、PointLight
等。
我希望将Light
的所有后代存储在该lights vector
中,如下所示:
template<typename T>
unique_ptr<T> CreateLight()
{
static_assert(std::is_base_of<Light, T>::value, "Type must of descendant of type Light. ");
unique_ptr<T> light(new T());
lights->emplace_back(light);
return light;
}
这种方法的原因是我将我的光源存储在我的renderer
集合中,这将发挥其魔力使光源影响着色器。
编辑
这些集合是名为Scene
的类的一部分。我一直需要它们,我需要将所有Light
实例都放在堆上(以及Scene
类拥有的所有其他实例(。Renderer
的每一帧都将经历灯光集合,以影响场景对象的着色器。在任何给定时间访问此向量至关重要。
不过,我仍然需要对场景中光源的引用,以便我可以操作其属性。
错误消息如下:
Severity Code Description Project File Line Suppression State
Error C2664 'std::unique_ptr<Light,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)': cannot convert argument 1 from 'std::unique_ptr<DirectionalLight,std::default_delete<_Ty>>' to 'std::nullptr_t'
这会在生成期间失败,而不是在运行时失败。 当然,我看了一下这样的答案,但无济于事。
我需要帮助来解决这个问题。
我有很多
Light
类的后代,比如DirectionalLight
,PointLight
等等。我希望将所有Light
的后代存储在 那点光矢量是这样的。
然后你只需要一个unique_ptr<Light>
的向量,而不是指向unique_ptr<Light>
向量的指针;这是一种过度设计的做事方式。
std::vector< std::unique_ptr<Light> > lights;
然后,您可以轻松处理所有事情。
template<typename T>
void CreateLight()
{
static_assert(std::is_base_of<Light, T>::value, "Type must of descendant of type Light. ");
// store to vector directly
lights.emplace_back( std::make_unique<T>(/*args*/));
}
如何获取新创建的轻量级实例,以便返回它?
由于您在 vector 的最后一个有新创建的实例lights
因此您可以直接在任何地方使用它。看这里
//Either directly
auto iter = lights.rbegin();
if(*iter) std::cout << "Donen";
// or
auto lastElement = std::move(lights.back());
if(lastElement) std::cout << "Donen";
lights->emplace_back(light);
更改为:
lights->emplace_back(new T());
您可以简单地返回对新创建对象的引用:
std::vector<std::unique_ptr<Light>>* lights;
template<typename T, typename... Args>
T& CreateLight(Args&&... args)
{
...
auto light = std::make_unique<T>(std::forward<Args>(args)...);
lights->push_back(std::move(light));
return *static_cast<T*>(lights->back().get());
}
在阅读了JeJo的答案后,修改了CreateLight
,使其接受任意数量的参数(包括零个(来构造T
。