tôi là tạo ra một logger với các phần sau:stringstream tạm ostream trở lại vấn đề
// #define LOG(x) // for release mode
#define LOG(x) log(x)
log(const string& str);
log(const ostream& str);
Với ý tưởng làm:
LOG("Test");
LOG(string("Testing") + " 123");
stringstream s;
LOG(s << "Testing" << 1 << "two" << 3);
này tất cả các công trình như dự định, nhưng khi tôi làm:
LOG(stringstream() << "Testing" << 1 << "two" << 3);
Nó không làm việc:
void log(const ostream& os)
{
std::streambuf* buf = os.rdbuf();
if(buf && typeid(*buf) == typeid(std::stringbuf))
{
const std::string& format = dynamic_cast<std::stringbuf&>(*buf).str();
cout << format << endl;
}
}
kết quả trong 'định dạng' chứa dữ liệu rác thay vì chuỗi chính xác thông thường.
Tôi nghĩ rằng điều này là do luồng thời gian tạm thời được trả về bởi nhà cung cấp < < làm nổi bật chuỗi xuất phát.
Hoặc tôi có sai không?
(Tại sao string() làm việc theo cách này? Có phải vì nó sẽ trả về một tham chiếu đến chính nó? Tôi giả định là có.)
Tôi thực sự muốn làm điều đó theo cách này như tôi sẽ bị loại bỏ phân bổ bổ sung khi đăng nhập ở chế độ phát hành.
Bất kỳ con trỏ hoặc thủ thuật nào để thực hiện theo cách này sẽ được hoan nghênh. Trong giải pháp thực tế của tôi, tôi có nhiều chức năng đăng nhập khác nhau và tất cả chúng phức tạp hơn thế này. Vì vậy, tôi muốn thực hiện điều này bằng cách nào đó trong mã gọi. (Và không bằng cách sửa đổi #define tôi nếu có thể)
Chỉ cần đưa ra một ý tưởng, một ví dụ về một trong những # định nghĩa thực tế của tôi:
#define LOG_DEBUG_MSG(format, ...) \
LogMessage(DEBUG_TYPE, const char* filepos, sizeof(__QUOTE__(@__VA_ARGS__)), \
format, __VA_ARGS__)
mà phù hợp với varargs chức năng đăng nhập printf giống như dùng char *, string() và ostream() cũng như các hàm không vararg lấy string(), exception() và HRESULT.
Bạn có ý nghĩa gì bởi "nó không hoạt động"? –
Bạn nói đúng, bạn nên lấy một bản sao của chuỗi, do đó, 'định dạng' phải thuộc loại' std :: string' không thuộc loại 'const std :: string &'. Tuy nhiên, bạn có thể đặt 'dynamic_cast' vào biểu thức' cout' và mất hoàn toàn biến. – KayEss
Không, tôi không cần phải sao chép. Nội dung của chuỗi được trả về bởi str() được đảm bảo duy trì không đổi (giống như cách string :: c_str() hiện) giữa các lần gọi tiếp theo với các phương thức này. Đối với lý do tại sao tôi làm như vậy, tôi cần chuỗi định dạng vì tôi thực sự muốn truyền nó cho một hàm tham số duy nhất lấy một chuỗi hoặc phương thức VARARGS lấy một char * tùy thuộc vào các tham số khác được nhận. (Nhưng tất cả điều này nằm ngoài phạm vi câu hỏi của tôi - được trả lời thỏa đáng) – Marius