Lý
tôi cố gắng tránh tập trong C++ hoàn toàn. Tức là, tôi chỉ sử dụng các khởi tạo và khai báo các biến cục bộ là const
bất cứ khi nào có thể (tức là ngoại trừ các biến vòng lặp hoặc các bộ tích lũy).Bind tạm thời để tham chiếu không const
Bây giờ, tôi đã tìm thấy trường hợp điều này không hiệu quả. Tôi tin rằng đây là một mô hình chung nhưng đặc biệt nó nảy sinh trong tình huống sau đây:
Mô tả vấn đề
Hãy nói rằng tôi có một chương trình mà tải các nội dung của một tập tin đầu vào thành một chuỗi. Bạn có thể gọi công cụ bằng cách cung cấp tên tệp (tool filename
) hoặc bằng cách sử dụng luồng đầu vào chuẩn (cat filename | tool
). Bây giờ, làm thế nào để tôi khởi tạo chuỗi?
Sau đây không hoạt động:
bool const use_stdin = argc == 1;
std::string const input = slurp(use_stdin ? static_cast<std::istream&>(std::cin)
: std::ifstream(argv[1]));
Tại sao không làm việc này? Bởi vì nguyên mẫu của slurp
cần phải xem xét như sau:
std::string slurp(std::istream&);
Đó là, đối số i phi-const
và kết quả là tôi không thể gắn nó vào một tạm thời. Dường như không có cách nào xung quanh việc này bằng cách sử dụng một biến riêng biệt.
Ugly Cách giải quyết
Tại thời điểm này, tôi sử dụng các giải pháp sau đây:
std::string input;
if (use_stdin)
input = slurp(std::cin);
else {
std::ifstream in(argv[1]);
input = slurp(in);
}
Nhưng điều này được cọ xát với tôi một cách sai lầm. Trước hết, đó là mã nhiều hơn (trong SLOC) nhưng nó cũng sử dụng một if
thay vì biểu thức điều kiện logic (ở đây) hợp lý hơn và nó sử dụng chuyển nhượng sau khi khai báo mà tôi muốn tránh.
Có cách nào tốt để tránh kiểu khởi tạo gián tiếp này không? Sự cố có thể được khái quát hóa cho tất cả các trường hợp bạn cần phải thay đổi đối tượng tạm thời. Không phát trực tiếp theo cách không được thiết kế để đối phó với các trường hợp như vậy (luồng const
không có ý nghĩa gì, nhưng vẫn hoạt động trên luồng tạm thời có ý nghĩa)?
Tại sao 'static_cast' là cần thiết ở đây? –
@ n.m .: Trình biên dịch không thể xem qua '?:'. Cả hai mặt của ':' phải cùng loại. –
'slurp' đang làm gì? :) –