Bởi vì tôi thích một lớp lót (chúng rất hữu ích cho tất cả những thứ kỳ lạ, như bạn sẽ thấy ở phần cuối), đây là một giải pháp sử dụng std :: Tích lũy và C ++ 11 lambda:
std::accumulate(alist.begin(), alist.end(), std::string(),
[](const std::string& a, const std::string& b) -> std::string {
return a + (a.length() > 0 ? "," : "") + b;
} )
Tôi thấy cú pháp này hữu ích với toán tử luồng, nơi tôi không muốn có tất cả các loại logic kỳ lạ ngoài phạm vi hoạt động luồng, chỉ để thực hiện một phép nối chuỗi đơn giản. Hãy xem xét ví dụ câu lệnh trả về này từ phương thức định dạng một chuỗi bằng cách sử dụng toán tử dòng (sử dụng std;):
return (dynamic_cast<ostringstream&>(ostringstream()
<< "List content: " << endl
<< std::accumulate(alist.begin(), alist.end(), std::string(),
[](const std::string& a, const std::string& b) -> std::string {
return a + (a.length() > 0 ? "," : "") + b;
} ) << endl
<< "Maybe some more stuff" << endl
)).str();
Cập nhật:
Như đã được chỉ ra bởi @plexando trong các nhận xét, đoạn mã trên bị lỗi khi mảng bắt đầu với chuỗi trống do thực tế là kiểm tra "lần chạy đầu tiên" bị thiếu các lần chạy trước đó dẫn đến không có ký tự bổ sung và - thật kỳ lạ khi chạy kiểm tra "lần chạy đầu tiên" trên tất cả các lần chạy (tức là mã chưa được tối ưu hóa).
Giải pháp cho cả hai vấn đề này rất dễ dàng nếu chúng ta biết thực tế rằng danh sách có ít nhất một phần tử. OTOH, nếu chúng ta biết thực tế rằng danh sách không có ít nhất một phần tử, thì chúng ta có thể rút ngắn thời gian chạy hơn nữa.
Tôi nghĩ rằng mã kết quả không đẹp, vì vậy tôi đang thêm nó ở đây dưới dạng Giải pháp chính xác , nhưng tôi nghĩ rằng cuộc thảo luận ở trên vẫn có merrit:
alist.empty() ? "" :
++alist.begin(), alist.end(),
*alist.begin(),
[](auto& a, auto& b) { return a + "," + b; });
Ghi chú:
- Đối với các vùng chứa hỗ trợ truy cập trực tiếp đến phần tử đầu tiên, có lẽ tốt hơn nên sử dụng phần tử đó cho đối số thứ ba, thay vào đó
alist[0]
đối với vectơ.
- Theo thảo luận trong phần bình luận và trò chuyện, lambda vẫn thực hiện một số bản sao. Điều này có thể được giảm thiểu bằng cách sử dụng lambda (ít đẹp hơn) này thay thế:
[](auto&& a, auto&& b) -> auto& { a += ','; a += b; return a; })
(trên GCC 10) cải thiện hiệu suất hơn x10. Cảm ơn @Deduplicator về đề xuất. Tôi vẫn đang cố gắng tìm hiểu xem chuyện gì đang xảy ra ở đây.