无法将派生的 class 存储在基数 classes 的指针向量中
Unable to store derived class in a vector of pointer of base classes
我有这个collection:
vector<unique_ptr<Light>>* lights;
我有很多Light
class的后代,比如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;
}
使用此方法的原因是我将我的灯光存储在 collection 中用于我的 renderer
,这将发挥它的魔力使灯光影响着色器。
编辑
这些 collection 是名为 Scene
的 class 的一部分。我一直都需要它们,我需要将所有 Light
个实例放在堆上(连同 Scene
class 拥有的所有其他实例)。
Renderer
的每一帧都会通过 collection 灯光来影响场景 objects' 着色器。在任何给定时间访问此向量至关重要。
我仍然需要引用场景中的灯光,以便我可以操纵它的属性。
错误信息是这样的:
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'
这在构建期间失败,而不是运行时。
当然,我看了 this one 之类的答案,但无济于事。
我需要帮助来解决这个问题。
lights->emplace_back(light);
更改为:
lights->emplace_back(new T());
您可以简单地 return 引用新创建的对象:
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
.
的参数
I have many descendants of the Light
class, like DirectionalLight
,
PointLight
and so on. I wish to store all descendants of Light
within
that lights vector like so.
那么你只需要一个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*/));
}
how do I get the freshly created light instance so I can return it?
因为你在lights
vector 的最后有新创建的实例,你可以直接在任何你想用的地方使用它。 See here
//Either directly
auto iter = lights.rbegin();
if(*iter) std::cout << "Done\n";
// or
auto lastElement = std::move(lights.back());
if(lastElement) std::cout << "Done\n";
我有这个collection:
vector<unique_ptr<Light>>* lights;
我有很多Light
class的后代,比如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;
}
使用此方法的原因是我将我的灯光存储在 collection 中用于我的 renderer
,这将发挥它的魔力使灯光影响着色器。
编辑
这些 collection 是名为 Scene
的 class 的一部分。我一直都需要它们,我需要将所有 Light
个实例放在堆上(连同 Scene
class 拥有的所有其他实例)。
Renderer
的每一帧都会通过 collection 灯光来影响场景 objects' 着色器。在任何给定时间访问此向量至关重要。
我仍然需要引用场景中的灯光,以便我可以操纵它的属性。
错误信息是这样的:
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'
这在构建期间失败,而不是运行时。 当然,我看了 this one 之类的答案,但无济于事。
我需要帮助来解决这个问题。
lights->emplace_back(light);
更改为:
lights->emplace_back(new T());
您可以简单地 return 引用新创建的对象:
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
.
I have many descendants of the
Light
class, likeDirectionalLight
,PointLight
and so on. I wish to store all descendants ofLight
within that lights vector like so.
那么你只需要一个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*/));
}
how do I get the freshly created light instance so I can return it?
因为你在lights
vector 的最后有新创建的实例,你可以直接在任何你想用的地方使用它。 See here
//Either directly
auto iter = lights.rbegin();
if(*iter) std::cout << "Done\n";
// or
auto lastElement = std::move(lights.back());
if(lastElement) std::cout << "Done\n";