【发布时间】:2021-06-27 23:00:49
【问题描述】:
为什么我不能从 clone 函数返回 unique_ptr?我以为I could do this。
我有一个名为transform 的不同数学函数的基类。我有一个指向这种类型的指针容器,因为我使用的是多态性。例如,所有这些派生类都有不同的 log_jacobian 实现,这对统计算法很有用。
我在这个transform 类中使用unique_ptrs,所以我创建了一个(纯虚拟)clone 函数,它使新的unique_ptr 指向同一个数学transform 对象的深层副本.这个新对象与派生自 transform<float_t> 的类型相同,但它是独立的,因为不能有两个 unique_ptrs 指向同一事物。
template<typename float_t>
class transform{
...
virtual std::unique_ptr<transform<float_t>> clone() const = 0;
...
};
我的transform_container 班级一次拥有其中一些。毕竟,大多数统计模型都有不止一个参数。
template<typename float_t, size_t numelem>
class transform_container{
private:
using array_ptrs = std::array<std::unique_ptr<transform<float_t>>, numelem>;
array_ptrs m_ts;
unsigned m_add_idx;
...
auto get_transforms() const -> array_ptrs;
};
不过,我不确定为什么深层复制功能 get_transforms 不起作用。它用于制作副本,以及访问容器中的各个转换。运行一些测试时出现段错误。如果我在gdb 中运行它,它会明确地告诉我在错误之后带有注释的行。
template<typename float_t, size_t numelem>
auto transform_container<float_t,numelem>::get_transforms() const -> array_ptrs
{
array_ptrs deep_cpy;
for(size_t i = 0; i < numelem; ++i){
deep_cpy[i] = m_ts[i]->clone(); // this line
}
return deep_cpy;
}
我也尝试将std::move 输入deep_cpy[i] 并使用unique_ptr::reset,但无济于事。
编辑:
这里有一些其他相关的方法:一个为transform_container添加转换的方法,以及为个人transform添加的工厂方法:
template<typename float_t>
std::unique_ptr<transform<float_t> > transform<float_t>::create(trans_type tt)
{
if(tt == trans_type::TT_null){
return std::unique_ptr<transform<float_t> >(new null_trans<float_t> );
}else if(tt == trans_type::TT_twice_fisher){
return std::unique_ptr<transform<float_t> >(new twice_fisher_trans<float_t> );
}else if(tt == trans_type::TT_logit){
return std::unique_ptr<transform<float_t> >(new logit_trans<float_t> );
}else if(tt == trans_type::TT_log){
return std::unique_ptr<transform<float_t> >(new log_trans<float_t> );
}else{
throw std::invalid_argument("that transform type was not accounted for");
}
}
template<typename float_t, size_t numelem>
void transform_container<float_t, numelem>::add_transform(trans_type tt)
{
m_ts[m_add_idx] = transform<float_t>::create(tt);
m_add_idx++;
}
【问题讨论】:
-
numelem数组中的所有numelem元素都有效吗? IE。是否所有指针都已初始化并指向实际的transform<float_t>对象? -
minimal reproducible example 会很有帮助。我写了一个快速的玩具程序,它运行没有问题。
-
在有问题的行之前添加
if (!m_ts[i]) throw "oopsies";。摆脱偏执狂。 -
@Taylor:是的,你不能告诉一个不存在的东西来克隆它自己
-
另外,学习如何使用调试器;您将能够在崩溃时停止并检查变量。
标签: c++ c++11 unique-ptr move-semantics