2015-02-20 24 views
11

gcc 4.9 kullanılarak geleneksel araçlarla oluşturulan olduğu gibi karmaşık sayılar için hazır bilgisinin oluşturulacak türleri, örneğin, aynı olmadığını tespit:typeid (karmaşık <double> (0.0,1.0)) = typeid (1.0i)

typeid(complex<double>(0.0,1.0)) != typeid(1.0i) 
  1. Burada hata mı yapıyorum?
  2. Bu bir derleyici hatası mı yoksa amaçlanan standart davranış mı?
  3. Amaçlanan standart davranış: Arkadaki mantık nedir? Eksik MCVE

    #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; 
    } 
    

    Derleme talimatları ekleme

:

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

Çıktı:

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

İlginç değişmez bile uygun bir hayali sayı görünmüyor. (Ben bir şey bakan ediyorum eminim ...) Programın

+0

Bunu gerçekten derleyen bir kaynak listesine yerleştirme şansınız var mı? Ben * düşünüyorum * std :: karmaşık ', '_Complex', sanal sabitler için gnu uzantısı, ama bir MCVE'siz onun zor söyleyerek * nedir * aslında * yapıyorsun. – WhozCraig

+0

Güncelleme için teşekkürler. evet, farklı tipler. Bir zamanlar standart kütüphaneden, diğeri derleyici uzantısından. – WhozCraig

+2

[Sorunu C++ 14'te yeniden üretemiyorum] (http://coliru.stacked-crooked.com/a/1fbd46340ab9b14e) @WhozCraig 'i' (aynı zamanda?) C++ 14'teki bir son ekidir. C++ 11 modunda, gcc muhtemelen [bu uzantı] kullanır (https://gcc.gnu.org/onlinedocs/gcc/Complex.html) – dyp

cevap

20

davranış dil standart modda gcc'nin bağlıdır:

C99 karmaşık sayılar üreten bir gcc extension for a built-in literal suffix i yoktur. Bunlar, C++ 'da kullanılan "kullanıcı tanımlı" sınıfının (şablon uzmanlığı) std::complex<double> aksine _Complex double gibi türünde yerleşiklerdir.

C++ 14'te, C++ artık karmaşık sayılar için kullanıcı tanımlı yazım son eki i'a sahiptir. Yani, std::literals::complex_literals satır içi ad alanında bir complex<double> operator"" i(long double) işlevi.

Bu iki edebi ekleri yarışıyor: C++ 11 modunda

  • , yalnızca yerleşik uzatma mümkündür, ancak bir uzantısıdır. Bu nedenle, gcc sadece -std=gnu++11 modunda izin verir ve sizi bu konuda uyarır. Gariptir, clang -std=c++11 modunda bile izin verir.

  • sıkı C++ 14 modu (-std=c++14 veya -std=c++1y) olarak, dahili uzatma, (bildiğim kadarıyla söyleyebilirim) belirsizlik çıkarmak için kullanıcı tanımlı seçilmesi dolayısıyla gcc ve clang hem devre dışı bırakılmalıdır değişmez sonek. çınlama kullanıcı tanımlı soneki seçer ise GNU'ya uzantısı-C++ 14 mod -std=gnu++14, GCC

  • , dahili eki (geriye doğru uyumluluk için?) seçer. Bu garip görünüyor ve burada hata raporları aramanızı veya dosyalamanızı öneririm.

hangi edebi eki, sizi seçilir a bağlı olarak ya olsun gömme tip _Complex double ya da bazı std::complex<double>.

+0

Üstün yanıt. Kullanıcı tanımlı haberlerin şemsiyenin altına geldiğini unutmaya devam ediyorum. – WhozCraig