Tôi đã được chơi xung quanh với C++ 11 thời gian gần đây, và đã đưa ra các chức năng tổng hợp như sau:Trình biên dịch không cảnh báo về mất chính xác?
template <typename T>
inline T sum(const std::function<T (int)> &f, int initial, int end)
{
T retval = 0;
for(int k = initial; k <= end; k++) {
retval += f(k);
}
return retval;
}
Ý tưởng là tôi có thể vượt qua một hàm lambda và do đó có một chức năng gọn gàng và dễ đọc cho toán học tiền. sau đó tôi thử như sau:
int main()
{
std::array<double, 2> arr1 = {{ 0.5, 1.5 }},
arr2 = {{ 1.5, -0.5 }};
auto n = sum<int>([&](int k) { return arr1[k]*arr2[k]; }, // Precision loss!
0, 1);
return 0;
}
tôi biên soạn này sử dụng g ++ 4.6.3: g++ -Wall -pedantic -std=c++0x -o test main.cpp
và không đưa ra bất cứ lời cảnh báo về sự mất mát chính xác tôi nhận xét trong các bình luận của mã nguồn.
Có khá nhiều điều được nêu ở đây rằng sum<int>
là một điều xấu phải làm, nhưng nó có thể không rõ ràng trong các bối cảnh phức tạp hơn. Nếu trình biên dịch không nhận thấy giá trị trả về của hàm lambda của tôi là double
và cảnh báo tôi rằng tôi đang mất đi độ chính xác khi truyền tới int
? Có lý do cụ thể nào không?
Chức năng sẽ không nhận thức được độ chính xác do thời gian chạy thực hiện một phép ẩn ngầm trước khi truyền trong các đối số. Mặc dù vậy, trong một thế giới lý tưởng, ít nhất bạn cũng nên xem cảnh báo trong studio trực quan/IDE của bạn để phản ánh rằng điều này sẽ dẫn đến mất chính xác. nhưng đây không phải là loại điều kiểm tra đơn vị nào? – War
@Wardy trong một thế giới lý tưởng nó sẽ không biên dịch (tức là nó sẽ là một lỗi, không phải là một cảnh báo) mà không có một yêu cầu rõ ràng để gây ra sự mất mát chính xác này. –
ok ... cũng im một nhà phát triển C# và tôi phải đi theo các quy tắc của .net (không chắc chắn nếu bạn cũng đang sử dụng một trình biên dịch .net nhưng) nó tiểu bang trong tài liệu mà một loại ít chính xác dự kiến là một tiềm ẩn cast được áp dụng ... nó được coi là một tính năng của ngôn ngữ. Tôi đồng ý mặc dù ... một lỗi sẽ là giấc mơ tuyệt đối trong kịch bản của bạn nhưng không phổ biến cho nền tảng trong kinh nghiệm của tôi. – War