Tôi có hệ thống ghi nhật ký mà tôi đang tìm cách tắt một số thao tác chuỗi.Chức năng quá tải nơi thông số chỉ khác nhau theo hình elip
Hệ thống ghi nhật ký được sử dụng thông qua các macro chức năng mà sau đó chuyển tiếp đến một cuộc gọi chức năng duy nhất. Ví dụ. #define Warning(...) LogMessage(eWarning, __VA_ARGS__);
.
LogMessage sau đó thực hiện snprintf
vào bộ đệm mới và sau đó hiển thị thông báo đó cho bất kỳ mục tiêu nhật ký nào xảy ra được cài đặt; printf, OutputDebugString, v.v.
Thật không may, tôi đã gặp sự cố trong đó bộ đệm mà chúng tôi chưa có đủ lớn, do đó đầu ra bị cắt bớt. Tôi cũng nhận ra rằng phương thức này sẽ thất bại nếu thông báo đầu ra có các ký hiệu phần trăm trong đó, vì snprintf sẽ cố gắng xử lý các va_args. Cuối cùng, vì phần lớn các thông điệp tường trình của chúng tôi không sử dụng va_args, có vẻ như ngớ ngẩn để sao chép chuỗi chỉ để trình bày nó cho các logger.
Vì vậy, với nguyên mẫu chức năng của tôi, tôi có thể quá tải dựa trên sự hiện diện của dấu ba chấm không? Nói cách khác, tôi sẽ có thể giả định rằng tôi có thể làm điều gì đó như:
LogMessage(LogLevel, const char* message, ...);
LogMessage(LogLevel, const char* message);
nỗ lực google của tôi đã không mang lại bất cứ điều gì đặc biệt hữu ích (chỉ hiển thị với tôi rằng elip sẽ phù hợp nếu không có gì khác không, dao động từ của tôi yêu cầu rằng không có gì là kết quả phù hợp) và lần truy cập đầu tiên của tôi khi triển khai đã cho tôi một lỗi gọi hàm chức năng mơ hồ.
Với lỗi, tôi chỉ nên chấp nhận rằng tôi không thể làm điều này, nhưng tôi tự hỏi nếu nó chỉ là trình biên dịch tôi đang sử dụng hoặc nếu có thể tôi đang làm sai. Tôi có thể đạt được một hiệu ứng tương tự với
// edited version of what I really have to remove our local APIs,
// please excuse minor errors
const char* message = NULL;
char buffer[512];
va_list args;
va_start(args, format);
if(strcmp(format, "%s") == 0) {
message = va_arg(args, const char*);
}
else if (strchr(format, '%') == NULL) {
message = format;
}
else {
vsnprintf(buffer, 512, format, args);
message = buffer;
}
va_end(args);
... nhưng điều này có vẻ lãng phí trong trường hợp điển hình có thể được biết đơn giản chỉ bằng số tham số được truyền. Ví dụ. nếu dấu ba chấm không khớp với bất kỳ thứ gì, hãy chọn hàm khác? Nếu điều này không làm việc, có một phương pháp khác tôi có thể thử mà không yêu cầu người dùng quyết định với tên macro mà chức năng sẽ được gọi là? Thành thật mà nói, nó thậm chí không nhiều về "chất thải" một khi tôi nhận ra rằng nếu một người nào đó bất ngờ nói Error("Buffer not 100% full");
trong thông điệp tường trình của họ và nhận được "Buffer không 1007.732873e10ull" kết quả là.
Chỉnh sửa: Trong khi ví dụ của tôi đã được trả lời bằng cách "không làm điều đó", câu hỏi có thể tự trả lời được không?
Tôi đoán tôi không mua triết lý đó, thích được tự do trong những gì tôi chấp nhận và bảo thủ trong những gì tôi gửi. IMO, nếu tôi có thể thần thánh ý định của người dùng, tôi nên. Phần mềm thất bại trong lĩnh vực này chỉ đơn giản là do các lập trình viên thiếu kinh nghiệm là không thể tha thứ cho tôi. Và quan điểm của tôi rõ ràng là tôi không muốn ghi lại các chức năng này như chấp nhận các chuỗi định dạng printf * chỉ *, tôi muốn chúng đi theo một trong hai cách. –
Ngay sau khi bạn cho phép đối số kiểu printf, bạn * phải * giả định rằng đó là những gì họ đang có khi bạn nhìn thấy chúng, nếu không những người muốn sử dụng chúng sẽ không nhận được hành vi mà bạn mong đợi. Nó sẽ không hoạt động để thử và trộn liệu bạn có xử lý các đối số kiểu printf như các đối số kiểu printf hay không. Nó chỉ yêu cầu rắc rối. Bạn có thể kiểm tra xem chuỗi có hợp lệ cho sprintf hay không, nhưng đừng mong đợi nó hoạt động một cách sạch sẽ để chấp nhận các đối số kiểu printf và bỏ qua chúng cùng một lúc. –
Và xem xét có bao nhiêu vấn đề phát triển web có bởi vì trình duyệt chấp nhận html xấu, tôi không mua cho một thứ hai chấp nhận tự do nhưng được bảo thủ trong những gì bạn gửi là một ý tưởng tốt. Chúng ta sẽ tốt hơn nếu web không được xây dựng bằng triết lý đó. Đừng làm điều đó trong mã của riêng bạn nếu bạn có thể tránh nó. Chắc chắn, chương trình trong một cách mà giảm thiểu sai sót (ngay cả đối với người mới), nhưng không hy sinh chính xác trong hy vọng vô ích của nó làm việc tốt hơn. Nó sẽ không. –