2015-02-20 13 views
11

Sử dụng gcc 4.9 tôi thấy rằng loại được tạo ra với loại đen cho số phức là không giống như khi tạo ra bởi phương tiện thông thường, ví dụ:typeid (phức tạp <double> (0.0,1.0)) = typeid (1.0i)

typeid(complex<double>(0.0,1.0)) != typeid(1.0i) 
  1. Tôi có nhầm lẫn ở đây không?
  2. Đây có phải là lỗi trình biên dịch hoặc hành vi tiêu chuẩn dự định không?
  3. Nếu hành vi tiêu chuẩn dự định: Lý do cơ bản đằng sau là gì?

Thêm MCVE thiếu

#include <complex> 
using std::complex; 
using namespace std::literals::complex_literals; 

#include <iostream> 
using std::cout; 
using std::endl; 

#include <typeinfo> 

int main(int argc, char* argv[]) { 
    if (typeid(complex<double>(0.0, 1.0)) == typeid(1.0i)) 
     cout << "types are same as expected" << endl; 
    else 
     cout << "types are unexpectedly not the same" << endl; 

    cout << 1.0i*1.0i << endl; 
    cout << complex<double>(0.0, 1.0)*complex<double>(0.0, 1.0) << endl; 
} 

Compile hướng dẫn:

g++ -std=gnu++14 complex.cpp -o complex.exe 

Output:

types are unexpectedly not the same 
1 
(-1,0) 

Điều thú vị là các literal không thậm chí dường như là một số ảo thích hợp. (Tôi chắc chắn tôi nhìn ra một cái gì đó ...)

+0

Bất kỳ cơ hội nào bạn có thể đặt trong danh sách nguồn thực sự biên dịch? Tôi nghĩ * bạn đang sử dụng 'std :: complex ', khác với '_Complex', phần mở rộng gnu cho các hằng số tưởng tượng, nhưng không có MCVE câu nói khó * những gì bạn đang thực sự làm. – WhozCraig

+0

Cảm ơn bạn đã cập nhật. có, chúng là các loại khác nhau. Một lần là từ thư viện chuẩn, cái kia từ phần mở rộng của trình biên dịch. – WhozCraig

+2

[Không thể tạo lại vấn đề trong C++ 14] (http://coliru.stacked-crooked.com/a/1fbd46340ab9b14e) @WhozCraig 'i' là (cũng?) Một hậu tố bằng chữ trong C++ 14. Trong chế độ C++ 11, gcc có thể sử dụng [phần mở rộng này] (https://gcc.gnu.org/onlinedocs/gcc/Complex.html) – dyp

Trả lời

20

Hành vi của chương trình phụ thuộc vào ngôn ngữ tiêu chuẩn chế độ của gcc:

Có một gcc extension for a built-in literal suffix i sản xuất C99 số phức. Đó là riêng biệt được xây dựng trong các loại như _Complex double, trái ngược với lớp "do người dùng xác định" (chuyên môn mẫu) std::complex<double> được sử dụng trong C++.

Trong C++ 14, C++ hiện có hậu tố theo ngữ cảnh do người dùng xác định chữ số i cho số phức. Tức là, một hàm complex<double> operator"" i(long double) trong không gian tên nội tuyến std::literals::complex_literals.

Hai hậu tố đen đang cạnh tranh:

  • Trong ++ 11 chế độ C, chỉ có phần mở rộng tích hợp là có thể, nhưng nó một phần mở rộng. Do đó, gcc chỉ cho phép nó ở chế độ -std=gnu++11 và thậm chí cảnh báo bạn về nó. Kỳ lạ là đủ, clang cho phép nó ngay cả trong chế độ -std=c++11.

  • Trong nghiêm ngặt C++ 14 chế độ (-std=c++14 hoặc -std=c++1y), phần mở rộng tích hợp phải được vô hiệu hóa để loại bỏ sự mơ hồ (như xa như tôi có thể nói), vì thế cả hai gcc và kêu vang chọn người dùng định nghĩa hậu tố chữ.

  • Trong chế độ gnu-extension-C++ 14 -std=gnu++14, gcc chọn hậu tố được tích hợp sẵn (để tương thích ngược?), Trong khi clang chọn hậu tố do người dùng xác định. Điều này có vẻ kỳ lạ và tôi khuyên bạn nên tìm kiếm hoặc gửi báo cáo lỗi tại đây.

tùy thuộc vào hậu tố đen được chọn, bạn có thể nhận được các built-in loại _Complex double hoặc một số std::complex<double>.

+0

Câu trả lời nổi bật. Tôi tiếp tục quên rằng các chữ cái do người dùng định nghĩa xuất hiện dưới cái ô. – WhozCraig

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