Một lớp X không thể chứa nhiều bản sao của các phiên bản thực tế của lớp X, ngoại trừ một cách hợp lý.
Một nếu chúng ta có
struct X {
std::array<X, 2> data;
};
kích thước chỉ nhất có thể cho X
là vô cực, như sizeof(X)
= 2*sizeof(X)
và tất cả các loại bằng C++ có sizeof(X)>=1
.
C++ không hỗ trợ các loại vô hạn lớn.
Vấn đề thứ hai của bạn là trường hợp loại không phải là mẫu.
template<typename T, template<typename> class Tuple>
class tree
này có một loại T
và template
Tuple
. Đối số thứ hai không phải là loại.
template<typename T, std::size_t N>
using static_tree = tree<T, std::array<T, N>>;
đây, lập luận thứ hai của bạn là một loại, không phải là một mẫu.
template<std::size_t N>
struct array_of_size {
template<class T>
using result=std::array<T,N>;
};
template<typename T, std::size_t N>
using static_tree = tree<T, array_of_size<N>::template result>;
sẽ, ngoài "vấn đề kích thước vô hạn" ở trên, giải quyết vấn đề của bạn. Ở đây chúng tôi đang chuyển mẫu array_of_size<N>::result
đến tree
.
Để giải quyết vấn đề kích thước vô hạn, bạn phải con trỏ lưu trữ (hoặc thứ gì đó tương đương) trong mảng. Vì vậy, chúng tôi nhận được:
template<std::size_t N>
struct array_of_ups_of_size {
template<class T>
using result=std::array<std::unique_ptr<T>,N>;
};
template<typename T, std::size_t N>
using static_tree = tree<T, array_of_ups_of_size<N>::template result>;
và bây giờ static_tree của bạn có N
trẻ em, mỗi trong số đó là một unique_ptr
đến một tương tự static_tree
.
Điều này vẫn không hoạt động, do các vấn đề về phá hủy.
template<typename T, template<typename> class Tuple>
class tree
{
private:
T m_value;
Tuple<tree> m_children;
public:
~tree();
};
template<typename T, template<typename> class Tuple>
tree<T,Tuple>::~tree() = default;
Tôi nghĩ rằng các sửa lỗi ở trên, lạ như có thể.
Về cơ bản, khi bạn tạo mảng trẻ em, loại cây chưa hoàn thành. Tại hủy diệt, xóa được gọi. Tại thời điểm đó, cây phải được hoàn thành. Bằng cách trì hoãn các dtor, chúng tôi hy vọng đối phó với vấn đề.
Tôi không chắc chắn kỹ thuật này có bắt buộc đối với các mẫu không, nhưng nó là dành cho các lớp không phải mẫu.
Nếu bạn sở hữu 'tree', tại sao không làm cho' Tuple' một tham số kiểu chứ không phải là một bản mẫu tham số? –
@AlanStokes Làm cách nào để xác định 'static_tree' trong trường hợp đó? Đó sẽ là một sự đệ quy vô tận, phải không? – 0xbadf00d
Thực tế là 'std :: array' cần tham số nguyên. Không có cách nào xung quanh chỉ định nó * đâu đó *. Đối với nơi này, có rất nhiều lựa chọn thay thế, và của bạn không xa rõ ràng. – davidhigh