尝试"复制"shared_ptr向上转换行为会导致复制构造函数上的无限递归(导致段错误)
Trying to 'replicate' shared_ptr upcasting behaviour cause an infinite recursion on copy constructor (that lead to a segfault)
我正在尝试复制shared_ptr行为,以更好地理解模板元编程和 c++17 中的type_traits。具体来说,我想复制向上转换行为,即在没有任何显式强制转换的情况下将shared_ptr< Base >
shared_ptr< Derived >
分配/复制创建的机会。
类型检查正在工作,但是在尝试复制或分配派生对象时,我在复制构造函数中出现无限循环的段错误。
通用模板类
#pragma once
#include <memory>
#include <type_traits>
template <typename T>
class Generic {
public:
template <typename DerivedT>
using Assignable = typename std::enable_if<std::is_assignable<T, DerivedT>::value, Generic<T> &>::type;
Generic() : _ptr(nullptr) {}
Generic(T *ptr) : _ptr{ptr} {};
Generic(Generic && cptr) :
_ptr(std::move(cptr._ptr))
{}
Generic(const Generic & cptr) :
_ptr{cptr._ptr}
{}
template <typename DerivedT, typename = Assignable<DerivedT>>
Generic(const Generic<DerivedT> &cptr)
: Generic(static_cast<const Generic &>(cptr)._ptr)
{}
~Generic() = default;
Generic & operator=(Generic && cptr) = default;
Generic & operator=(const Generic & cptr) {
_ptr = cptr._ptr;
return *this;
}
template <typename DerivedT>
Assignable<DerivedT> operator=(const Generic<DerivedT> &cptr) {
_ptr = static_cast<const Generic &>(cptr)._ptr;
return *this;
}
private:
T* _ptr;
};
主.cpp
#include "Generic.hpp"
struct Base {
};
struct Derived : public Base {
};
int main() {
Generic<Derived> derived = Generic<Derived>();
Generic<Base> base(derived);
//Generic<Base> base = derived;
}
您的问题可以简化为:
template <typename T>
class Generic {
public:
Generic() = default;
Generic(T *ptr) : _ptr{ptr} {};
template <typename Derived>
Generic(const Generic<Derived> &cptr) :
Generic(static_cast<const Generic &>(cptr)._ptr)
{}
private:
T* _ptr = nullptr;
};
struct Base {
};
struct Derived : public Base {
};
int main() {
Generic<Derived> derived = Generic<Derived>();
Generic<Base> base(derived);
}
问题在于,使用static_cast<const Generic &>(cptr)
,您隐式地创建了Generic<T>
形式Generic<Derived>
的实例,从而递归地无限调用构造函数。
可能的解决方法是:
template <typename T>
class Generic {
public:
Generic() = default;
Generic(T *ptr) : _ptr{ptr} {};
template <typename Derived>
Generic(const Generic<Derived> &cptr) :
Generic(cptr._ptr)
{}
private:
T* _ptr = nullptr;
template <typename U>
friend class Generic;
};
struct Base {
};
struct Derived : public Base {
};
int main() {
Generic<Derived> derived = Generic<Derived>();
Generic<Base> base(derived);
}
相关文章:
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 使用strcpy将char数组的元素复制到另一个数组
- 是否可以初始化不可复制类型的成员变量(或基类)
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- C++ Windows 驱动程序MSB3030无法复制该文件,因为它找不到
- 复制列表初始化的隐式转换的等级是多少
- 当从函数参数中的临时值调用复制构造函数时
- 有可能在Armadillo中复制MATLAB circshift方法吗
- 复制几乎为空的数组的最快方法
- 以下示例中如何避免代码复制?C++/库达
- 如果有一个模板构造函数只有一个泛型参数,为什么我必须有一个复制构造函数
- 为什么需要复制构造函数,在哪些情况下它们非常有用
- 不能将复制初始化与隐式转换的多个步骤一起使用
- 当有分配器意识的容器被复制/移动时,反弹分配器是否被复制/移走
- visual是否可以在c++中创建一个接收无限数量相同类型(或至少相当数量)参数的函数
- 为什么复制而不是移动数据元素?
- 文件系统:复制功能的速度秘诀是什么
- 尝试"复制"shared_ptr向上转换行为会导致复制构造函数上的无限递归(导致段错误)
- 二叉搜索树的复制构造函数被无限调用