class Namespace::Class;
Mengapa saya harus melakukan ini ?:
namespace Namespace {
class Class;
}
Menggunakan VC ++ 8.0, masalah kompiler:
kesalahan C2653: 'Namespace': bukan nama kelas atau namespace
Saya berasumsi bahwa masalahnya di sini adalah bahwa kompiler tidak dapat menentukan apakah Namespace
kelas atau namespace? Tapi mengapa ini penting karena itu hanya deklarasi maju?
Apakah ada cara lain untuk meneruskan-mendeklarasikan kelas yang didefinisikan dalam beberapa namespace? Sintaks di atas terasa seperti saya "membuka kembali" namespace dan memperluas definisinya. Bagaimana jika Class
sebenarnya tidak didefinisikan dalam Namespace
? Apakah ini akan menghasilkan kesalahan di beberapa titik?
c++
namespaces
Yong Li
sumber
sumber
A::B
dalamA
adalah identifier namespace bukan nama kelas?Namespace
kelas atau namespace. Hanya saja, jangan mendekati petunjuk kemungkinan memulai perang api bahasa atas sintaksis.Jawaban:
Karena kamu tidak bisa. Dalam bahasa C ++ nama yang sepenuhnya memenuhi syarat hanya digunakan untuk merujuk entitas yang ada (yaitu yang sebelumnya dinyatakan). Mereka tidak dapat digunakan untuk memperkenalkan entitas baru .
Dan Anda berada pada kenyataannya "membuka kembali" namespace untuk menyatakan entitas baru. Jika kelas
Class
nanti didefinisikan sebagai anggota namespace yang berbeda - itu adalah kelas yang sama sekali berbeda yang tidak ada hubungannya dengan yang Anda nyatakan di sini.Setelah Anda sampai pada titik mendefinisikan kelas pra-deklarasi, Anda tidak perlu "membuka kembali" namespace lagi. Anda dapat mendefinisikannya di namespace global (atau namespace yang melampirkan Anda
Namespace
) sebagaiKarena Anda merujuk ke entitas yang telah dideklarasikan di namespace
Namespace
, Anda dapat menggunakan nama yang memenuhi syaratNamespace::Class
.sumber
Anda mendapatkan jawaban yang benar, izinkan saya mencoba kembali kata-kata:
class Namespace::Class;
Anda harus melakukan ini karena istilahnya
Namespace::Class
memberitahu compiler:Tetapi kompiler tidak tahu apa yang Anda bicarakan karena tidak tahu nama namespace
Namespace
. Bahkan jika ada namespace bernamaNamespace
, seperti pada:itu masih tidak akan berhasil, karena Anda tidak dapat mendeklarasikan kelas di dalam namespace dari luar namespace itu. Anda harus berada di namespace.
Jadi, Anda sebenarnya bisa maju mendeklarasikan kelas dalam namespace. Lakukan saja ini:
sumber
Saya kira itu karena alasan yang sama Anda tidak dapat mendeklarasikan ruang nama bersarang dalam satu cara seperti ini:
dan Anda harus melakukan ini:
sumber
Tidak akan jelas apa sebenarnya tipe variabel yang dinyatakan maju. Deklarasi maju
class Namespace::Class;
bisa berartiatau
sumber
Ada banyak jawaban bagus tentang alasan yang digunakan untuk menolaknya. Saya hanya ingin memberikan klausa standar yang membosankan yang secara khusus melarangnya. Ini berlaku untuk C ++ 17 (n4659).
Paragraf yang dimaksud adalah [class.name] / 2 :
Di atas mendefinisikan apa yang merupakan deklarasi maju (atau redclaration dari suatu kelas). Pada dasarnya, itu harus salah satu dari
class identifier;
,struct identifier;
atau diunion identifier;
mana identifer adalah definisi leksikal yang umum di [lex.name] :Yang merupakan produksi dari skema umum yang
[a-zA-Z_][a-zA-Z0-9_]*
kita semua kenal. Seperti yang Anda lihat, ini menghalangiclass foo::bar;
untuk menjadi deklarasi maju yang valid, karenafoo::bar
bukan pengenal. Itu nama yang sepenuhnya memenuhi syarat, sesuatu yang berbeda.sumber