2008-12-10 19 views
34

Bugün, SO üzerinde birileri, başlık dosyalarında anonim ad alanlarını kullanmamanız gerektiğini iddia etti. Normalde bu doğrudur, ama birisi bana standart kitaplıklardan birinin, bir çeşit başlatma işlemini gerçekleştirmek için başlık dosyalarında anonim ad alanlarını kullandığını söylediğini hatırlıyorum.Başlık dosyalarındaki anonim ad alanlarını kullanır

Doğru hatırlıyor muyum? Birisi detayları doldurabilir mi?

+1

bu tartışma bakınız: [http://stackoverflow.com/questions/357404/anonynous-namespaces](http://stackoverflow.com/questions/357404/anonynous-namespaces) –

+0

o iplik var başlıklarda bu anonim ad alanlarından bu bilgileri aldım nerede –

+0

Bu başlıkta başlık dosyaları kullanarak hakkında hiçbir şey bulamıyorum. Bunun neden yanlış olduğunu kimse anlatabilir mi? Ve hala C++ 11'de geçerli mi? – baruch

cevap

20

başlığında isimsiz ad yararlı olabilir tek durum budur sen başlık dosyaları yalnızca kod dağıtmak istediğinizde. Örneğin, Boost'un bağımsız tek bir alt kümesi yalnızca başlıklardır.

Başka bir yanıtta sözü edilen başlıklar için ignore belirteci bir örnektir, _1, _2 vb.

+0

Ben bununla iyi bir noktaya yaptığınızı düşünüyorum. –

+0

Anonim ad alanını, ad alanı çakışmasına yol açabilecek son derleme biriminde birlikte çöktüğü için kullanmamalısınız. Bunun yerine, kural gereği, içeriğin uygulama ayrıntıları olduğu anlamına gelen bir ad kullanın. Boost, örneğin, 'detail' kullanır. – thehouse

+0

@thehouse Boost'un anonim ad alanlarını nasıl kullandığını yanlış anlamış görünüyorsunuz. 'görmezden gelin' ve '_1', '_2' vb. kamusal simgelerdir - onlar' detay''a ait değildir. Ancak, bir ayrıntı ad alanının normalde bir başlık kütüphanesinin anonim bir ad alanı eşdeğeri için doğru seçim olduğuna katılıyorum. –

2

Başlıklardaki anonim ad alanlarını kullanmanın olumlu bir faydasını gerçekten göremiyorum. Aynı sembol bildirimine sahip olmasından kaynaklanan karışıklık, özünde, bu başlığı içeren derleme birimlerinde farklı bir şey, erken ve ağrılı bir şekilde kelleşmenin garantili bir yolu olacaktır.

0

Eğer başlangıç ​​durumuna getiriliyorsa, büyük olasılıkla iostream s başlığı (istream, ios, vb.) Olacaktır.

13

Başlık dosyasında anonim bir ad alanı koymanın hiçbir noktasını göremiyorum. Ben standart ve libstdC++ başlıklarını grepped ettik tuple başlığında birinin dışında hiçbir anonim ad alanlarını bulundu (C++ 1x şeyler):

// A class (and instance) which can be used in 'tie' when an element 
    // of a tuple is not required 
    struct _Swallow_assign 
    { 
    template<class _Tp> 
     _Swallow_assign& 
     operator=(const _Tp&) 
     { return *this; } 
    }; 

    // TODO: Put this in some kind of shared file. 
    namespace 
    { 
    _Swallow_assign ignore; 
    }; // anonymous namespace 

Bu yüzden size

std::tie(a, std::ignore, b) = some_tuple; 

yapabilirsiniz some_tuple öğelerinin öğeleri sol taraftaki değişkenlere atanır (bkz. here), benzer bir teknik this yineleyici için kullanılır. İkinci eleman göz ardı edilir.

Ama dedikleri gibi, bir .cpp dosyasına konulmalı ve bir örnek tüm kullanıcılar tarafından paylaşılmalıdır. Onlar bu o zaman böyle başlığına bunun bir deklarasyon koyardı:

extern _Swallow_assign ignore; 
+0

C++ 1x? Bir şey mi kaçırdım? –

+0

sonraki C++ sürümü –

+0

Sutter hala bunu çağırıyor C++ 0x (http://herbsutter.wordpress.com/2008/10/28/september-2008-iso-c-standards-meeting-the-draft-has-landed -ve-a-yeni-Düzenleyicisi /). –

4

Farklı çeviri birimlerindeki bir değişken için varsayılan bir değer sağlamak için kullanılır gördüm. Fakat isim çatışması durumunda beklenmedik davranışlara neden olabilir.

Örnek

a.hpp

namespace 
{ 
    const char name[] = "default"; 
} 
// This macro will hide the anonymous variable "name" 
#define SET_NAME(newname) \ 
static const char name[] = newname; 

b.cpp

#include "a.hpp" 
SET_NAME("file b") // name is "file b" in this translation unit 

c.cpp

#include "a.hpp" 
SET_NAME("file c") // name is "file c" in this translation unit 

d.cpp

#include "a.hpp" 
// name is "default" in this translation unit 

e.cpp

#include "a.hpp" 
static const char name[] = "unintended"; 
// accidently hiding anonymous name