我正在尝试复制 shared_ptr 行为以更好地理解 c++17 中的模板元编程和 type_traits。
具体来说,我想复制向上转换行为,即分配/复制创建的机会 shared_ptr< Derived >
至 shared_ptr< Base >
没有任何显式转换。
类型检查工作正常,但在尝试复制或分配派生对象时,我在复制构造函数中遇到无限循环的段错误。
通用模板类
#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++ - 尝试 'replicate' shared_ptr 向上转换行为导致复制构造函数无限递归(导致段错误),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56456882/