Apakah ada cara yang lebih baik untuk mengekspresikan namespace bertingkat di C ++ dalam header

98

Saya beralih dari C ++ ke Java dan C # dan berpikir penggunaan namespace / paket jauh lebih baik di sana (terstruktur dengan baik). Kemudian saya kembali ke C ++ dan mencoba menggunakan namespace dengan cara yang sama tetapi sintaks yang diperlukan sangat buruk di dalam file header.

namespace MyCompany
{
    namespace MyModule
    {
        namespace MyModulePart //e.g. Input
        {
            namespace MySubModulePart
            {
                namespace ...
                {
                    public class MyClass    

Hal berikut juga tampak aneh bagi saya (untuk menghindari indentasi yang dalam):

namespace MyCompany
{
namespace MyModule
{
namespace MyModulePart //e.g. Input
{
namespace MySubModulePart
{
namespace ...
{
     public class MyClass
     {

Apakah ada cara yang lebih singkat untuk mengungkapkan hal di atas? Saya kehilangan sesuatu seperti

namespace MyCompany::MyModule::MyModulePart::...
{
   public class MyClass

Memperbarui

Ok, ada yang bilang konsep penggunaan di Java / C # dan C ++ berbeda. Betulkah? Saya pikir pemuatan kelas (dinamis) bukan satu-satunya tujuan untuk ruang nama (ini adalah perspektif beralasan yang sangat teknis). Mengapa saya tidak menggunakannya untuk keterbacaan dan penataan, misalnya memikirkan "IntelliSense".

Saat ini, tidak ada logika / perekat antara namespace dan apa yang dapat Anda temukan di sana. Java dan C # melakukan ini jauh lebih baik ... Mengapa menyertakan <iostream>dan memiliki namespace std? Oke, jika Anda mengatakan logika harus bergantung pada tajuk untuk menyertakan, mengapa #include tidak menggunakan sintaks ramah "IntelliSense" seperti #include <std::io::stream>or <std/io/stream>? Saya pikir strukturisasi yang hilang di libs default adalah salah satu kelemahan C ++ dibandingkan dengan Java / C #.

Jika keunikan untuk avid konflik adalah satu Titik (yang juga merupakan titik C # dan Java), ide yang bagus adalah menggunakan nama proyek atau nama perusahaan sebagai namespace, bukan begitu?

Di satu sisi dikatakan C ++ adalah yang paling fleksibel ... tetapi semua orang berkata "jangan lakukan ini"? Menurut saya C ++ dapat melakukan banyak hal tetapi memiliki sintaksis yang mengerikan bahkan untuk hal yang paling mudah dalam banyak kasus dibandingkan dengan C #.

Perbarui 2

Sebagian besar pengguna mengatakan tidak masuk akal untuk membuat sarang yang lebih dalam dari dua Tingkat. Ok, jadi bagaimana dengan Windows :: UI :: Xaml dan Windows :: UI :: Xaml :: Controls :: Primitives namespaces dalam pengembangan Win8? Saya pikir penggunaan namespace Microsoft masuk akal dan memang lebih dalam dari hanya 2 Level. Saya pikir perpustakaan / proyek yang lebih besar membutuhkan penyarangan yang lebih dalam (saya benci nama kelas seperti ExtraLongClassNameBecauseEveryThingIsInTheSameNameSpace ... maka Anda juga dapat memasukkan semuanya ke dalam namespace global.)

Perbarui 3 - Kesimpulan

Sebagian besar mengatakan "jangan lakukan itu", tetapi ... bahkan peningkatan memiliki tingkat yang lebih dalam daripada satu atau dua tingkat. Ya, ini adalah perpustakaan tetapi: Jika Anda menginginkan kode yang dapat digunakan kembali - perlakukan kode Anda sendiri seperti perpustakaan yang akan Anda berikan kepada orang lain. Saya juga menggunakan penyarangan yang lebih dalam untuk tujuan penemuan menggunakan ruang nama.

Beachwalker
sumber
3
Apakah ini penyalahgunaan namespacekata kunci?
Nawaz
4
namespaces dan c # / sistem modul java tidak memiliki tujuan yang sama, karena itu Anda tidak boleh mencoba menggunakannya dengan cara yang sama. dan tidak, tidak ada sintaks yang lebih sederhana, karena tidak masuk akal untuk memberikan sintaks untuk membuat hal-hal lebih mudah dilakukan, yang tidak dimaksudkan untuk dilakukan.
PlasmaHH
@ PlasmaHH ... jadi kelemahannya adalah strukturisasi std lib C ++ hilang? (lihat contoh sederhana saya dalam pembaruan)
Beachwalker
@Stegi: Jika Anda dapat memberikan argumen yang masuk akal mengapa hal itu hilang, dan manfaat kuat apa yang akan kami dapatkan dari penataan seperti itu, kami dapat berbicara tentang potensi kelemahan. Sampai saat itu saya akan menyebut javas bersarang tanpa akhir dari paket yang paling membingungkan.
PlasmaHH
3
@PlasmaHH Intellisense dan pembantu lainnya untuk / setelah penyertaan header (paket). Proyek besar dalam satu perusahaan mungkin memerlukan lebih dari satu bersarang (mis. Vw :: golflib :: io) untuk pernyataan yang jelas tentang isi namespace di mana "cakupan". Nah, Anda bisa saja menggunakan vw :: tetapi jika namespace dimaksudkan untuk digunakan untuk menghindari bentrokan, mengapa begitu mengerikan untuk dideklarasikan? Ini berakhir pada titik di mana tidak ada yang menggunakannya atau hanya menggunakan namespace dengan kedalaman satu (seperti yang sering disarankan).
Beachwalker

Jawaban:

132

C ++ 17 mungkin menyederhanakan definisi namespace bersarang:

namespace A::B::C {
}

setara dengan

namespace A { namespace B { namespace C {
} } }

Lihat (8) di halaman namespace di cppreference:
http://en.cppreference.com/w/cpp/language/namespace

W1M0R
sumber
5
... diaktifkan oleh sakelar kompiler/std:c++latest
bulan cerah
4
Perhatikan, bahwa jika Anda akan menggunakan /std:c++latestVisual Studio 2015 dan juga menggunakan Boost, Anda mungkin mengalami kesalahan kompiler yang sangat mistis saat Anda menyertakan beberapa header Boost. Saya menghadapi masalah ini seperti yang dijelaskan dalam pertanyaan StackOverflow ini
Vivit
1
Ia bekerja sebagaimana adanya, namespace A :: B :: C. Saya telah menguji dengan g ++ - 6.0
ervinbosenbacher
31

Untuk menghindari indentasi yang sangat dalam, saya biasanya melakukannya dengan cara ini:

namespace A { namespace B { namespace C
{
    class X
    {
        // ...
    };
}}}
Kurt Hutchinson
sumber
3
JFYI clang-formattidak dapat memformatnya saat Anda menampilkan clang.llvm.org/docs/ClangFormatStyleOptions.html (NamespaceIndentation)
KindDragon
17

Saya sepenuhnya mendukung jawaban peterchen tetapi ingin menambahkan sesuatu yang menjawab bagian lain dari pertanyaan Anda.

Mendeklarasikan namespaces adalah salah satu kasus yang sangat jarang terjadi di C ++ di mana saya sebenarnya suka penggunaan #defines.

#define MY_COMPANY_BEGIN  namespace MyCompany { // begin of the MyCompany namespace
#define MY_COMPANY_END    }                     // end of the MyCompany namespace
#define MY_LIBRARY_BEGIN  namespace MyLibrary { // begin of the MyLibrary namespace
#define MY_LIBRARY_END    }                     // end of the MyLibrary namespace

Ini juga menghilangkan kebutuhan akan komentar di dekat tanda kurung kurawal tutup ruang nama (Apakah Anda pernah menggulir ke bawah ke bagian bawah file sumber besar dan mencoba menambahkan / menghapus / menyeimbangkan tanda kurung yang tidak ada komentar tentang tanda kurung yang menutup cakupan yang mana? Tidak menyenangkan .).

MY_COMPANY_BEGIN
MY_LIBRARY_BEGIN

class X { };

class Y { };

MY_LIBRARY_END
MY_COMPANY_END

Jika Anda ingin meletakkan semua deklarasi namespace dalam satu baris, Anda juga dapat melakukannya dengan sedikit keajaiban preprocessor (sangat jelek):

// helper macros for variadic macro overloading
#define VA_HELPER_EXPAND(_X)                    _X  // workaround for Visual Studio
#define VA_COUNT_HELPER(_1, _2, _3, _4, _5, _6, _Count, ...) _Count
#define VA_COUNT(...)                           VA_HELPER_EXPAND(VA_COUNT_HELPER(__VA_ARGS__, 6, 5, 4, 3, 2, 1))
#define VA_SELECT_CAT(_Name, _Count, ...)       VA_HELPER_EXPAND(_Name##_Count(__VA_ARGS__))
#define VA_SELECT_HELPER(_Name, _Count, ...)    VA_SELECT_CAT(_Name, _Count, __VA_ARGS__)
#define VA_SELECT(_Name, ...)                   VA_SELECT_HELPER(_Name, VA_COUNT(__VA_ARGS__), __VA_ARGS__)

// overloads for NAMESPACE_BEGIN
#define NAMESPACE_BEGIN_HELPER1(_Ns1)             namespace _Ns1 {
#define NAMESPACE_BEGIN_HELPER2(_Ns1, _Ns2)       namespace _Ns1 { NAMESPACE_BEGIN_HELPER1(_Ns2)
#define NAMESPACE_BEGIN_HELPER3(_Ns1, _Ns2, _Ns3) namespace _Ns1 { NAMESPACE_BEGIN_HELPER2(_Ns2, _Ns3)

// overloads for NAMESPACE_END
#define NAMESPACE_END_HELPER1(_Ns1)               }
#define NAMESPACE_END_HELPER2(_Ns1, _Ns2)         } NAMESPACE_END_HELPER1(_Ns2)
#define NAMESPACE_END_HELPER3(_Ns1, _Ns2, _Ns3)   } NAMESPACE_END_HELPER2(_Ns2, _Ns3)

// final macros
#define NAMESPACE_BEGIN(_Namespace, ...)    VA_SELECT(NAMESPACE_BEGIN_HELPER, _Namespace, __VA_ARGS__)
#define NAMESPACE_END(_Namespace, ...)      VA_SELECT(NAMESPACE_END_HELPER,   _Namespace, __VA_ARGS__)

Sekarang Anda bisa melakukan ini:

NAMESPACE_BEGIN(Foo, Bar, Baz)

class X { };

NAMESPACE_END(Baz, Bar, Foo) // order doesn't matter, NAMESPACE_END(a, b, c) would work equally well

Foo::Bar::Baz::X x;

Untuk bersarang lebih dari tiga level, Anda harus menambahkan makro pembantu hingga jumlah yang diinginkan.

Max Truxa
sumber
Meskipun saya tidak suka #define, saya cukup terkesan dengan keajaiban preprocessor itu ... hanya jika saya tidak perlu menambahkan makro pembantu tambahan untuk penyarangan yang lebih dalam ... yah, saya tidak akan menggunakannya, jadi .. .
galdin
13

Namespace C ++ digunakan untuk mengelompokkan antarmuka, bukan untuk membagi komponen atau mengungkapkan divisi politik.

Standar berusaha keras untuk melarang penggunaan namespace seperti Java. Misalnya, alias namespace menyediakan cara untuk dengan mudah menggunakan nama namespace yang bertingkat atau panjang.

namespace a {
namespace b {
namespace c {}
}
}

namespace nsc = a::b::c;

Tapi namespace nsc {}kemudian akan menjadi kesalahan, karena namespace hanya dapat didefinisikan menggunakan nama-namespace-aslinya . Pada dasarnya standar membuat hal-hal mudah bagi pengguna perpustakaan seperti itu tetapi sulit bagi pelaksana . Ini membuat orang enggan menulis hal-hal seperti itu tetapi mengurangi efeknya jika mereka melakukannya.

Anda harus memiliki satu namespace per antarmuka yang ditentukan oleh sekumpulan kelas dan fungsi terkait. Sub-antarmuka internal atau opsional mungkin masuk ke ruang nama bersarang. Tetapi lebih dari dua tingkat seharusnya menjadi tanda bahaya yang sangat serius.

Pertimbangkan untuk menggunakan karakter garis bawah dan awalan pengenal jika ::operator tidak diperlukan.

Potatoswatter
sumber
17
Ok, jadi bagaimana dengan Windows :: UI :: Xaml dan Windows :: UI :: Xaml :: Controls :: Primitives namespaces dalam pengembangan Win8? Saya pikir penggunaan namespace Microsoft masuk akal dan memang lebih dalam dari hanya 2 Level.
Beachwalker
2
Menggunakan kurang dari 2 level adalah tanda bahaya dan menggunakan 3 atau 4 baik-baik saja. Mencoba mencapai hierarki namespace datar ketika tidak masuk akal mengalahkan tujuan namespace - menghindari bentrokan nama. Saya setuju bahwa Anda harus memiliki satu level untuk antarmuka dan satu lagi untuk subinterfaces dan internal. Tetapi sekitar itu Anda memerlukan setidaknya satu level lagi untuk namespace perusahaan (untuk perusahaan kecil hingga menengah) atau dua untuk perusahaan dan divisi (untuk perusahaan besar). Jika tidak, ruang nama antarmuka Anda akan berbenturan dengan yang dari antarmuka lain dengan nama yang sama yang dikembangkan di tempat lain
Kaiserludi
@Kaiserlud Apa keuntungan teknis dari company::divisionover company_division?
Potatoswatter
@Potatoswatter Di dalam perusahaan :: anotherDivsion Anda bisa menggunakan 'divisi' yang lebih pendek. untuk merujuk ke perusahaan :: divisi bahkan di dalam tajuk di mana Anda harus menghindari polusi ruang nama tingkat yang lebih tinggi dengan menggunakan 'menggunakan ruang nama'. Di luar namespace perusahaan Anda masih dapat melakukan 'menggunakan perusahaan namespace;' ketika nama divisi tidak bertabrakan dengan namespace lain dalam lingkup Anda, tetapi ketika nama antarmuka di dalam beberapa namespace divisi bertabrakan sehingga Anda tidak dapat melakukan 'menggunakan namespace company_division;'.
Kaiserludi
3
@Potatoswatter Intinya adalah Anda mendapatkannya secara praktis secara gratis (company :: division tidak lebih lama dari company_division) dan tidak perlu mendefinisikan alias namespace tambahan terlebih dahulu untuk menggunakannya.
Kaiserludi
7

Tidak, dan tolong jangan lakukan itu.

Tujuan utama namespace adalah menyelesaikan konflik di namespace global.

Tujuan sekunder adalah singkatan lokal dari simbol; misalnya UpdateUImetode kompleks dapat menggunakan using namespace WndUIuntuk menggunakan simbol yang lebih pendek.

Saya menggunakan proyek 1.3MLoc, dan satu-satunya namespace yang kami miliki adalah:

  • mengimpor perpustakaan COM eksternal (terutama untuk mengisolasi konflik header antara #importdan #include windows.h)
  • Satu level ruang nama "API publik" untuk aspek tertentu (UI, akses DB, dll.)
  • Ruang nama "Detail Implementasi" yang bukan bagian dari API publik (ruang nama anonim di .cpp's, atau ModuleDetailHereBeTygersruang nama di lib hanya header)
  • enum adalah masalah terbesar dalam pengalaman saya. Mereka mencemari seperti orang gila.
  • Saya masih merasa itu terlalu banyak ruang nama

Dalam proyek ini, nama kelas, dll. Menggunakan kode "wilayah" dua atau tiga huruf (misalnya, CDBNodebukan DB::CNode). Jika Anda lebih suka yang terakhir, ada ruang untuk namespace "publik" tingkat kedua, tapi tidak lebih.

Enum khusus kelas, dll. Dapat menjadi anggota kelas tersebut (meskipun saya setuju ini tidak selalu baik, dan terkadang sulit untuk mengatakan apakah Anda harus)

Namespace "perusahaan" juga jarang dibutuhkan, kecuali jika Anda mengalami masalah besar dengan pustaka pihak ketiga yang didistribusikan sebagai biner, jangan berikan namespace mereka sendiri, dan tidak dapat dengan mudah dimasukkan ke dalamnya (mis. Dalam biner distribusi). Namun, menurut pengalaman saya, memaksa mereka ke dalam namespace jauh lebih mudah dilakukan.


[sunting] Sesuai pertanyaan tindak lanjut Stegi:

Ok, jadi bagaimana dengan Windows :: UI :: Xaml dan Windows :: UI :: Xaml :: Controls :: Primitives namespaces dalam pengembangan Win8? Saya pikir penggunaan namespace Microsoft masuk akal dan memang lebih dalam dari hanya 2 Level

Maaf jika saya tidak cukup jelas: Dua level bukanlah batas yang sulit, dan lebih banyak tidak buruk secara intrinsik. Saya hanya ingin menunjukkan bahwa Anda jarang membutuhkan lebih dari dua, dari pengalaman saya, bahkan pada basis kode yang besar. Bersarang lebih dalam atau lebih dangkal adalah pengorbanan.

Sekarang, kasus Microsoft bisa dibilang berbeda. Agaknya tim yang jauh lebih besar, dan semua kodenya adalah perpustakaan.

Saya berasumsi Microsoft meniru di sini keberhasilan Pustaka .NET, di mana ruang nama berkontribusi pada penemuan pustaka yang luas. (.NET memiliki sekitar 18000 jenis.)

Saya selanjutnya akan berasumsi bahwa ada simbol (urutan besarnya) yang optimal dalam namespace. katakanlah, 1 tidak masuk akal, 100 terdengar benar, 10000 jelas terlalu banyak.


TL; DR: Ini tradeoff, dan kami tidak memiliki angka pasti. Bermain aman, jangan berlebihan ke segala arah. Kalimat "Jangan lakukan itu" hanya berasal dari "Kamu bermasalah dengan itu, aku punya masalah dengan itu, dan aku tidak melihat alasan mengapa kamu membutuhkannya.".

peterchen
sumber
8
Ok, jadi bagaimana dengan Windows :: UI :: Xaml dan Windows :: UI :: Xaml :: Controls :: Primitives namespaces dalam pengembangan Win8? Saya pikir penggunaan namespace Microsoft masuk akal dan memang lebih dalam dari hanya 2 Level.
Beachwalker
2
Jika saya membutuhkan konstanta akses global, saya ingin meletakkannya di namespace dengan nama seperti Constants, lalu membuat namespace bersarang dengan nama yang sesuai untuk mengkategorikan konstanta; jika perlu, saya kemudian menggunakan ruang nama lebih lanjut untuk mencegah benturan nama. Ini Constantsnamespace sendiri terkandung dalam menangkap semua namespace untuk kode sistem program, dengan nama seperti SysData. Hal ini menciptakan nama lengkap memenuhi syarat yang mengandung tiga atau empat ruang nama (seperti SysData::Constants::ErrorMessages, SysData::Constants::Ailments::Bitflags, atau SysData::Defaults::Engine::TextSystem).
Waktu Justin - Kembalikan Monica
1
Ketika konstanta diperlukan dalam kode aktual, fungsi apa pun yang membutuhkannya menggunakan usingarahan untuk memasukkan nama yang sesuai, meminimalkan kemungkinan nama yang saling bertentangan. Saya merasa itu meningkatkan keterbacaan, dan membantu mendokumentasikan ketergantungan blok kode yang diberikan. Terlepas dari konstanta, saya cenderung mencoba dan menyimpannya di dua ruang nama jika memungkinkan (seperti SysData::Exceptionsdan SysData::Classes).
Waktu Justin - Kembalikan Monica
2
Secara keseluruhan, saya akan mengatakan bahwa dalam kasus umum, yang terbaik adalah menggunakan jumlah minimal ruang nama bersarang, tetapi jika Anda memerlukan objek global untuk beberapa alasan (apakah konstan atau bisa berubah, sebaiknya yang pertama), beberapa ruang nama bersarang harus digunakan untuk memisahkannya ke dalam kategori yang sesuai, baik untuk mendokumentasikan penggunaannya dan meminimalkan potensi benturan nama.
Waktu Justin - Kembalikan Monica
2
-1 untuk "tolong jangan lakukan ini" tanpa alasan obyektif mengapa (meskipun akan dijelaskan nanti). Bahasa ini mendukung ruang nama bersarang dan proyek mungkin memiliki alasan bagus untuk menggunakannya. Diskusi tentang kemungkinan alasan tersebut dan kerugian konkret dan obyektif apa pun untuk melakukannya akan membalikkan suara negatif saya.
TypeIA
5

Berikut kutipan dari dokumen Lzz (Lazy C ++):

Lzz mengenali konstruksi C ++ berikut:

definisi namespace

Namespace tanpa nama dan semua deklarasi terlampir adalah keluaran ke file sumber. Aturan ini mengesampingkan yang lainnya.

Nama namespace bernama mungkin memenuhi syarat.

   namespace A::B { typedef int I; }

setara dengan:

   namespace A { namespace B { typedef int I; } }

Tentu saja kualitas sumber yang bergantung pada alat semacam itu masih bisa diperdebatkan ... Saya akan mengatakan ini lebih merupakan keingintahuan, menunjukkan bahwa penyakit sintaksis yang disebabkan oleh C ++ dapat mengambil banyak bentuk (saya juga punya milik saya ...)

CapelliC
sumber
2

Kedua standar (C ++ 2003 dan C ++ 11) sangat eksplisit bahwa nama namespace adalah pengenal. Artinya, header bertingkat eksplisit diperlukan.

Kesan saya bahwa ini bukan masalah besar untuk memungkinkan penempatan pengenal yang memenuhi syarat selain nama sederhana dari namespace, tetapi untuk beberapa alasan hal ini tidak diperbolehkan.

Kirill Kobelev
sumber
2

Makalah ini membahas subjek dengan cukup baik: Namespace Paper

Yang pada dasarnya intinya ini. Semakin panjang ruang nama Anda, semakin besar kemungkinan orang akan menggunakan using namespacearahan tersebut.

Jadi melihat kode berikut, Anda dapat melihat contoh di mana ini akan merugikan Anda:

namespace abc { namespace testing {
    class myClass {};
}}

namespace def { namespace testing {
    class defClass { };
}}

using namespace abc;
//using namespace def;

int main(int, char**) {
    testing::myClass classInit{};
}

Kode ini akan dikompilasi dengan baik, namun, jika Anda menghapus komentar pada baris //using namespace def;maka namespace "pengujian" akan menjadi ambigu dan Anda akan mengalami benturan penamaan. Ini berarti basis kode Anda dapat berubah dari stabil menjadi tidak stabil dengan menyertakan pustaka pihak ketiga.

Di C #, bahkan jika Anda menggunakan using abc;dan using def;kompilator dapat mengenali itu testing::myClassatau bahkan myClasshanya di abc::testingnamespace, tetapi C ++ tidak akan mengenali ini dan itu terdeteksi sebagai tabrakan.

Dipertanyakan
sumber
0

Ya, Anda harus melakukannya seperti

namespace A{ 
namespace B{
namespace C{} 
} 
}

Namun, Anda mencoba menggunakan ruang nama dengan cara yang tidak seharusnya digunakan. Memeriksa pertanyaan ini , mungkin Anda akan merasa berguna.

SingerOfTheFall
sumber
0

Anda dapat menggunakan sintaks ini:

namespace MyCompany {
  namespace MyModule {
    namespace MyModulePart //e.g. Input {
      namespace MySubModulePart {
        namespace ... {
          class MyClass;
        }
      }
    }
  }
}

// Here is where the magic happens
class MyCompany::MyModule::MyModulePart::MySubModulePart::MyYouGetTheIdeaModule::MyClass {
    ...
};

Perhatikan bahwa sintaks ini valid bahkan di C ++ 98 dan hampir mirip dengan yang sekarang tersedia di C ++ 17 dengan definisi namespace bertingkat .

Selamat bersenang-senang!

Sumber:

smac89
sumber
Itu adalah sytax yang disebutkan dalam pertanyaan di mana solusi yang lebih baik dicari sebagai gantinya. Sekarang, dengan C ++ 17 adalah alternatif valid yang tersedia seperti yang dinyatakan oleh jawaban yang diterima. Maaf, tidak suka karena tidak membaca pertanyaan dan jawaban.
Beachwalker
@Beachwalker jangan sampai terjebak pada sintaks. Deklarasi ruang nama di atas bisa jadi sama dengan jawaban yang diterima. Poin utama yang ingin saya soroti dengan jawaban ini adalah apa yang dikatakan OP yang dia lewatkan, dan apa yang saya lakukan di bawah kekacauan namespace itu. Sejauh yang saya lihat, semua orang tampaknya telah fokus untuk mendeklarasikan segala sesuatu di dalam namespace, sedangkan jawaban saya membawa Anda keluar dari kekacauan bersarang dan saya yakin OP akan menghargai sintaks ini jika ada yang menyebutkannya 4 tahun yang lalu ketika pertanyaan ini pertama kali ditanyakan.
smac89
-1

[EDIT:]
Karena c ++ 17 namespace bersarang didukung sebagai fitur bahasa standar ( https://en.wikipedia.org/wiki/C%2B%2B17 ). Untuk saat ini, fitur ini tidak didukung di g ++ 8, tetapi dapat ditemukan di kompiler clang ++ 6.0.


[KESIMPULAN:]
Gunakan clang++6.0 -std=c++17sebagai perintah kompilasi default Anda. Maka semuanya akan bekerja dengan baik - dan Anda akan dapat mengkompilasinya namespace OuterNS::InnerNS1::InnerNS2 { ... }dalam file Anda.


[ASLI JAWABAN:]
Karena pertanyaan ini agak lama, saya anggap Anda sudah pindah. Tetapi untuk orang lain, yang masih mencari jawaban, saya datang dengan ide berikut:

Buffer Emacs menampilkan file utama, file namespace, perintah / hasil kompilasi, dan eksekusi baris perintah.

(Bolehkah saya memasang iklan Emacs di sini :)?) Mengirim gambar jauh lebih mudah, dan lebih mudah dibaca, daripada sekadar kode pos. Saya tidak bermaksud untuk memberikan jawaban penuh dari semua kasus sudut, saya hanya bermaksud untuk memberikan beberapa inspirasi. (Saya sepenuhnya mendukung C # dan merasa bahwa dalam banyak kasus C ++ harus mengadopsi beberapa fitur OOP, karena C # populer terutama karena perbandingan kemudahan penggunaan).

ワ イ き ん ぐ
sumber
Pembaruan: Karena C ++ 17 memiliki namespacing bersarang ( nuonsoft.com/blog/2017/08/01/c17-nested-namespaces ), tampaknya jawaban saya tidak lagi relevan, kecuali jika Anda menggunakan versi C ++ yang lebih lama .
ワ イ き ん ぐ
1
Meskipun saya menyukai Emacs, memposting gambar tidaklah ideal. Ini menghindari pencarian teks / pengindeksan, dan juga membuat jawaban Anda sulit diakses oleh pengunjung tunanetra.
Heinrich mendukung Monica