Nói rằng tôi có mã dưới đây (rất đơn giản).
#include <iostream>
int main() {
std::cout << std::stoi("12");
}
Điều này biên dịch tốt trên cả g ++ và clang; tuy nhiên, nó không thể biên dịch trên MSVC với lỗi sau:
lỗi C2039: 'stoi': không phải là thành viên của 'std'
lỗi C3861: 'stoi': không tìm thấy định danh
Tôi biết đó std::stoilà một phần của <string>tiêu đề, có lẽ hai trình biên dịch trước bao gồm một phần <iostream>và phần sau thì không. Theo tiêu chuẩn C ++ [res.on.headers]
Một tiêu đề C ++ có thể bao gồm các tiêu đề C ++ khác.
Trong đó, với tôi, về cơ bản nói rằng cả ba trình biên dịch đều đúng.
Vấn đề này phát sinh khi một trong những học sinh của tôi nộp bài, mà TA đánh dấu là không biên dịch; Tôi tất nhiên đã đi và sửa nó. Tuy nhiên, tôi muốn ngăn chặn những sự cố trong tương lai như thế này. Vì vậy, có cách nào để xác định tập tin tiêu đề nào nên được đưa vào, không cần biên dịch trên ba trình biên dịch khác nhau để kiểm tra mỗi lần?
Cách duy nhất tôi có thể nghĩ đến là đảm bảo rằng đối với mọi stdlệnh gọi hàm, bao gồm một hàm thích hợp; nhưng nếu bạn có mã hiện có dài hàng nghìn dòng, điều này có thể rất tẻ nhạt để tìm kiếm. Có cách nào dễ dàng / tốt hơn để đảm bảo khả năng tương thích chéo của trình biên dịch không?
Ví dụ với ba trình biên dịch: https://godbolt.org/z/kJhS6U
std::stoingay lập tức bạn chắc chắn #include <string>cũng có mặt.
std::stoilà để xử lý các chuỗi, bạn có thể đoán đó<string>sẽ là một tiêu đề tốt để đưa vào. Hoặc bạn có thể tìm kiếm một tài liệu tham khảo tốt sẽ cho bạn biết. Và tôi khuyên bạn luôn luôn bao gồm các tệp tiêu đề một cách rõ ràng, vì vậy bạn không cần phải dựa vào hành vi cụ thể thực hiện không di động.