Tham chiếu sẽ tồn tại trong toàn bộ vòng đời container
, nhưng đối tượng đang được tham chiếu sẽ chỉ tồn tại trong suốt thời gian tồn tại của đối tượng đó. Trong trường hợp này, bạn đã ràng buộc tham chiếu đến một đối tượng tạm thời với phân bổ lưu trữ tự động ("phân bổ ngăn xếp", nếu bạn sẽ, mặc dù đó không phải là danh mục C++). Do đó, bạn không thể mong đợi tạm thời tồn tại ngoài tuyên bố mà nó được viết (vì nó nằm ngoài phạm vi ngay lập tức sau khi gọi hàm tạo cho container
). Cách tốt nhất để giải quyết vấn đề này là sử dụng bản sao thay vì tham chiếu. Vì bạn đang sử dụng tham chiếu const, dù sao, nó sẽ có ngữ nghĩa tương tự.
Bạn nên xác định lại lớp học của bạn như:
template<typename T>
class container
{
public:
container(const T& first, const T& second) : first(first), second(second) {}
private:
const T first;
const T second;
};
Ngoài ra, bạn có thể cung cấp cho đối tượng của bạn một tên để ngăn chặn chúng từ đi ra khỏi phạm vi:
adaptor first;
adaptor second;
container c(first,second);
Tuy nhiên, tôi không nghĩ rằng đây là một ý tưởng hay, vì một tuyên bố như return c
không hợp lệ.
Sửa
Nếu mục tiêu của bạn là để chia sẻ đối tượng để tránh chi phí sao chép, sau đó bạn nên xem xét sử dụng đối tượng con trỏ thông minh.Ví dụ, chúng ta có thể xác định lại đối tượng của bạn sử dụng con trỏ thông minh như sau:
template<typename T>
class container
{
public:
container(const boost::shared_ptr<const T>& first, const boost::shared_ptr<const T>& second) : first(first), second(second) {}
private:
boost::shared_ptr<const T> first;
boost::shared_ptr<const T> second;
};
Sau đó bạn có thể sử dụng:
boost::shared_ptr<const adaptor> first(new adaptor);
boost::shared_ptr<const adaptor> second(new adaptor);
container<adaptor> c(first,second);
Hoặc, nếu bạn muốn có bản sao có thể thay đổi các đầu tiên và thứ hai tại địa phương:
boost::shared_ptr<adaptor> first(new adaptor);
boost::shared_ptr<adaptor> second(new adaptor);
container<adaptor> c(boost::const_pointer_cast<const adaptor>(first),boost::const_pointer_cast<const adaptor>(second));
Tôi nghĩ rằng trong trường hợp này, tạm thời bị ràng buộc với tham số cuộc gọi hàm (gọi hàm dựng) như trong câu tiếp theo. Có, nó cũng bị ràng buộc với thành viên vì bí danh trong bộ khởi tạo ctor, và có, nó sẽ tồn tại cho đến khi các hàm khởi tạo (dài hơn, trên thực tế, nếu biểu thức đầy đủ chứa lời gọi hàm tạo cũng làm những việc khác). Nhưng tôi nghĩ đoạn văn được đánh dấu đề cập đến những thứ như 'struct container {const & adapter a; container(): a (adapter()) {}}; '. –
@Steve: nhìn kỹ hơn, tôi nghĩ bạn nói đúng - Tôi sẽ cập nhật câu trả lời (cùng một kết quả). –