global statis dan ruang nama anonim di C ++


11
  1. Mengapa C ++ membuat perbedaan antara global statis (hubungan internal) dan simbol dalam ruang nama yang tidak disebutkan namanya (hubungan eksternal, toh tidak ada cara untuk merujuknya dari luar), ketika memperkenalkan yang terakhir?

  2. Adakah alasan-alasan itu yang masih berlaku, atau ada yang baru?

  3. Apakah ada tempat tersisa di mana mereka masih berbeda tetapi aturan sewenang-wenang yang harus dimiliki oleh serikat global (atau namespace-lingkup) anonimstatic , dan apakah mereka?

  4. Untuk poin bonus, jika tidak ada alasan yang tersisa bagi mereka untuk berbeda, apakah ada permintaan untuk membuatnya setara?


Ketika C ++ memperkenalkan ruang nama (C ++ 98), dan secara khusus ruang nama yang tidak disebutkan namanya, global statis dihilangkan sebagai usang dan kalah dengan hal baru dalam pertarungan antusiasme, meskipun itu dikembalikan dengan C ++ 11 :
Penghentian kata kunci statis ... tidak lagi?

Sebelum C ++ 11, simbol dengan tautan internal tidak dapat digunakan sebagai argumen templat: Mengapa C ++ 03 memerlukan parameter templat untuk memiliki tautan eksternal?


Sepertinya Anda sebagian besar telah menjawab pertanyaan Anda sendiri, kecuali untuk bagian "sesuaikan implementasi"; mungkin Anda harus mempertimbangkan menghapus babak kedua dan mempostingnya sebagai jawaban? Atau masih ada sesuatu yang belum terjawab di sini?
Kyle Strand

@KyleStrand Merumuskan ulang semuanya.
Deduplicator

Jawaban:


3

Saya tidak mengira ini menjawab semua pertanyaan Anda (atau salah satu dari mereka?), Tetapi perbedaan utama antara deklarasi statis tingkat file dan ruang nama anonim adalah bahwa ruang nama juga berlaku untuk jenis (Anda tidak dapat mendeklarasikan staticjenis di sama seperti Anda mendeklarasikan variabel), itu sebabnya namespace lebih disukai, jadi ada idiom tunggal untuk mendeklarasikan data dan tipe file-scoped.

Sebagai contoh, kode berikut harus dikompilasi dengan baik. (Tidak terlalu berguna, karena Anda tidak dapat membedakan kedua jenis, tetapi diizinkan)

#include <iostream>

struct Foobar
{
    int   foo;
    float bar;
};

namespace
{

struct Foobar
{
    double baz;
};

} // namespace

int main()
{
    std::cout << "HELLO!\n";
}

Tes langsung di sini .


Ini mengkompilasi karena Anda tidak menggunakan Foobar di fungsi utama.
dshil

Lebih penting lagi apa yang terjadi jika file .cpp lain mendeklarasikan versinya sendiri struct Foobar? Lebih buruk lagi, anggaplah sekarang class Foobar. Pikirkan bagaimana Anda berencana membuat konstruktor untuk keduanya.
dgnuff
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.