Saya belajar tentang fungsi overloading di C ++ dan menemukan ini:
void display(int a)
{
cout << "int" << endl;
}
void display(unsigned a)
{
cout << "unsigned" << endl;
}
int main()
{
int i = -2147483648;
cout << i << endl; //will display -2147483648
display(-2147483648);
}
Dari apa yang saya pahami, nilai apa pun yang diberikan dalam int
kisaran (dalam kasus saya int
adalah 4 byte) akan memanggil display(int)
dan nilai apa pun di luar kisaran ini akan menjadi ambigu (karena penyusun tidak dapat memutuskan fungsi mana yang akan dipanggil). Ini valid untuk rentang int
nilai lengkap kecuali nilai minnya, yaitu di -2147483648
mana kompilasi gagal dengan kesalahan
panggilan overloaded
display(long int)
ambigu
Tapi mengambil nilai yang sama int
dan mencetak nilai yang diberikan 2147483648
. Saya benar-benar bingung dengan perilaku ini.
Mengapa perilaku ini diamati hanya ketika angka paling negatif dilewatkan? (Perilakunya sama jika a short
digunakan dengan -32768
- pada kenyataannya, dalam kasus apa pun di mana bilangan negatif dan bilangan positif memiliki representasi biner yang sama)
Kompiler yang digunakan: g ++ (GCC) 4.8.5
sumber
call of overloaded ‘display(long int)’ is ambiguous
.typeof(-2147483648) != int
. Literalnya adalah2147483648
, yang terlalu besar untuk sebuahint
, jadi itu along
, dan itu sedang dinegasikanint j{-2147483648};
ini adalah konversi yang mempersempit. Hampir layak menjadi pertanyaan tersendiri, itu. Ini mungkin terkait dengan mengizinkan (misalnya)long long
nilai-nilai konstekspr seperti yang2147483647LL
dipersempit dalam inisialisasi.Jawaban:
Ini adalah kesalahan yang sangat halus. Apa yang Anda lihat adalah konsekuensi dari tidak adanya literal integer negatif dalam C ++. Jika kita melihat [lex.icon] kita mendapatkan bahwa literal-integer ,
bisa berupa desimal-literal ,
di mana digit adalah
[0-9]
dan nol-digit adalah[1-9]
dan akhiran par dapat menjadi salah satu dariu
,U
,l
,L
,ll
, atauLL
. Tidak ada di sini yang memasukkannya-
sebagai bagian dari literal desimal.Dalam §2.13.2, kami juga memiliki:
(penekanan saya)
Yang artinya
-
in-2147483648
adalah unaryoperator -
. Artinya-2147483648
sebenarnya diperlakukan sebagai-1 * (2147483648)
. Karena2147483648
satu terlalu banyak untuk Anda,int
itu dipromosikan menjadi along int
dan ambiguitas berasal dari ketidaksesuaian itu.Jika Anda ingin mendapatkan nilai minimum atau maksimum untuk suatu jenis secara portabel, Anda dapat menggunakan:
std::numeric_limits<type>::min(); // or max()
sumber
-2147483647 - 1
juga akan bekerja tanpa peringatan sebagai ekspresi literal negatifINT_MIN
untuk opsi verbose terkecil. Kurang umum.display(2147483649);
. Mengapa tidak dapat memanggil fungsi int unsigned dalam kasus ini? dan mengapa itu memperlakukan arg2147483649
as long int daripada unsigned int?int
kelong int
kelong long int
. Anda tidak akan pernah mendapatkan tipe unsigned untuk literal desimal kecuali Anda menggunakan sufiksu
/U
.display(unsigned a)
Anda perludisplay(1234u);
ataudisplay(static_cast<unsigned>(1234));
atauunsigned foo = 1234; display(foo);
Ekspresi
-2147483648
sebenarnya menerapkan-
operator ke konstanta2147483648
. Di platform Anda,int
tidak bisa menyimpan2147483648
, itu harus diwakili oleh tipe yang lebih besar. Oleh karena itu, ekspresi-2147483648
tidak disimpulkan menjadisigned int
tetapi tipe bertanda tangan yang lebih besarsigned long int
,.Karena Anda tidak memberikan kelebihan beban
long
, kompilator dipaksa untuk memilih di antara dua beban berlebih yang keduanya sama-sama valid. Kompilator Anda harus mengeluarkan kesalahan kompilator tentang kelebihan beban yang ambigu.sumber
Memperluas jawaban orang lain
Untuk memperjelas mengapa OP bingung, pertama : pertimbangkan
signed int
representasi biner2147483647
, di bawah ini.Berikutnya, tambahkan satu ke nomor ini : memberikan lain
signed int
dari-2147483648
(yang OP ingin digunakan)Akhirnya: kita dapat melihat mengapa OP bingung ketika
-2147483648
mengkompilasi ke a,long int
bukan asigned int
, karena jelas cocok dalam 32 bit.Tapi, seperti jawaban saat ini menyebutkan, operator unary (
-
) diterapkan setelah menyelesaikan2147483648
yang merupakanlong int
dan TIDAK muat dalam 32 bit.sumber