2012-06-19 25 views
16

Các mã sau đây với VS2010 in 0, trái với mong đợi của tôi:Tại sao abs (phức tạp <int>) luôn trả về 0?

#include <complex> 
#include <iostream> 

using namespace std; 

int main(void) 
{ 
    complex<int> z(20, 200); 
    cout << abs<int>(z) << endl; 
    return 0; 
} 

Nó hoạt động tốt khi loại là double.

Trả lời

23

Theo spec C++ ISO, § 26,2/2:

Hiệu quả của instantiating mẫu complex cho bất kỳ loại khác hơn float, double hoặc long double là không xác định.

Nói cách khác, trình biên dịch có thể thực hiện bất cứ điều gì bạn muốn khi bạn khởi tạo complex<int>. Thực tế là bạn đang nhận được 0 ở đây là hoàn toàn được xác định rõ hành vi từ một quan điểm ngôn ngữ.

Để so sánh - trên ideone's version of gcc, mã này thậm chí không biên dịch. Đó là một lựa chọn hoàn toàn hợp lệ khác.

Hy vọng điều này sẽ hữu ích!

+0

Huh, tôi thậm chí không được phép sử dụng loại số thực của riêng mình? Thật đáng thất vọng. –

+0

@ PaulManta- Vâng, tôi đoán là không. Tôi không biết tại sao lại như thế. – templatetypedef

+1

Cảm ơn bạn đã trả lời. Quay trở lại 0, 200 hoặc 42 khi hành vi không xác định có thể thực sự theo một tiêu chuẩn, nhưng chắc chắn nó là một pitfall khá cho lập trình viên bình thường như tôi. – Artium

6

Trên MinGW 4.6.2 nó in 200.

Tuy nhiên, trong C++ tiêu chuẩn ISO phần 26.2.2 Phép:

Hiệu quả của instantiating mẫu complex cho bất kỳ loại khác hơn float, double hoặc long double là không xác định.

Vì vậy, môi trường xây dựng của bạn thể hiện hành vi không xác định cho complex<int>, không trái với tiêu chuẩn.

templatetypedef chỉ ra, ideone's C99 compiler (GCC 4.3.4) từ chối biên dịch hoàn toàn.

+0

Nó thực sự là [4.5.1] (http://ideone.com/pLiug). – Puppy

+0

@DeadMG - Phiên bản được sử dụng trong ví dụ 'templatetypedef' là 4.3.4, cho C99. Liên kết của bạn sử dụng C++ 0x, là phiên bản 4.5.1, xem [trang này] (http://ideone.com/samples#sample_lang_44) – Unsigned

Các vấn đề liên quan