SORU
9 HAZİRAN 2014, PAZARTESİ


Ekstra parantez etkisi, operatör önceliği başka var mı?

Parantez içinde C birçok yerde kullanılır: işlev çağrıları ve gruplandırma ifadeler örneğin operatör önceliği geçersiz kılmak için.Yasadışı ekstra parantez dışında(işlev çağrısı bağımsız değişken listesi gibi), genel -mutlak - C kural değil buekstra parantez asla zarar:

5.1 İlköğretim ifadeler [ifade.prim]

5.1.1 Genel ifade.prim.genel]

6 ayraçlı Bir ifade olan primer bir ifadesidir ve değer kapalı ifadenin aynıdır. Varlığı parantez olup olmadığını etkilemez ifadesi bir lvalue. Programlama dilinde * sembolü ifade tam olarak aynı bağlamlarda kullanılabilir aynı kapalı bir ifade kullanıldığı gibi, anlamı,aksi belirtilmediği sürece.

Soru: hangi bağlamlarda ekstra parantez C programının anlamı, temel operatör önceliği geçersiz kılma dışında değişir mi?

NOT: Ben ve kısıtlama düşününişaretçi üyesi65 ** farklı anlamlar içeren iki sözdizimi izin vermek yerine, çünkü parantez kapsamı dışında olmak olmadan &qualified-id sözdizimi. Benzer şekilde, kullanımıbasit makro tanımları içinde parantezaynı zamanda istenmeyen operatör önceliği karşı korur.

CEVAP
9 HAZİRAN 2014, PAZARTESİ


TL;DR

Ekstra parantez aşağıdaki bağlamlarda C programının anlamı değiştirmek:

  • bağımlı değişken önleme araması adı
  • listedeki virgül operatör sağlayan bağlamlar
  • can sıkıcı yapısının bir belirsizlik çözümlemesi
  • decltype ifadelerde deducing referenceness
  • basit makro hataları önlemek

Bağımlı değişken önleme araması adı

Olduğu gibi ayrıntılı olarak Ek Bir Standart, bir post-fix expression şeklinde (expression) primary expression ama id-expression, ve bu nedenle bir unqualified-id. Bu bağımlı değişken adı araması 15 ** geleneksel formuna göre form (fun)(arg) işlev çağrıları engellenir anlamına gelir.

3.4.2 bağımlı Değişken adı arama [temel.arama.argdep]

1bir işlev çağrısı postfix-ifade (5.2.2). vasıfsız-ıddiğer ad olarak her zamankinden sırasında niteliksiz arama (3.4.1) aranan olabilir, ve bu ad, ad-kapsam arkadaş işlev veya işlev şablonu bildirimleri (11.3) aksi görünür bulunabilir. Bu değişiklikler arama argümanlar (ve şablon için türleri üzerinde bağlıdır bağımsız değişken, bağımsız değişken şablon ad). [ Örnek:

namespace N {
    struct S { };
    void f(S);
}

void g() {
    N::S s;
    f(s);   // OK: calls N::f
    (f)(s); // error: N::f not considered; parentheses
            // prevent argument-dependent lookup
}

uç bir örnek ]

Listedeki virgül operatör sağlayan bağlamlar

Virgül operatörünün listesi gibi içerikleri (fonksiyon ve şablon bağımsız değişken, başlatıcı listeleri vb.) çoğunda özel bir anlamı vardır. Bu bağlamlarda formu a, (b, c), d parantez virgül operatörü, virgül operatörü için geçerli değildir normal form a, b, c, d göre etkinleştirebilirsiniz.

5.18 Virgül operatörü [ifade.virgül]

2 virgül özel bir anlam verildiği bağlamlarda, Örneğiniçinde işlev için bağımsız değişken (5.2.2) ve başlatıcı listeleri listeleri (8.5)Fıkra 5 olabilir açıklandığı gibi uç örnek ] virgül operatörü sadece parantez içinde görünür. [ Örnek:

f(a, (t=3, t 2), c);

üç bağımsız değişkeni vardır, ikinci olan 5 değeri vardır. uç örnek ]

Can sıkıcı yapısının bir belirsizlik çözümlemesi

C ve arcane işlev bildirimi sözdizimini ile uyumluluk şaşırtıcı ayrıştırma belirsizlikler, can sıkıcı ayrıştırır olarak bilinen yol açabilir. Aslındabildirimi olarak ayrıştırılabilir bir şey ayrıştırılmasırakip bir ayrıştırma da geçerli olacak olsa bile.

6.8 Belirsizlik çözünürlük [stmt.ambig]

1Dilbilgisi içinde bir belirsizlik ifade ifadeleri içeren var ve bildirimleriBir ifade ile-bir ifade tarzı fonksiyonu en soldaki onun aradığına olarak açık tür dönüşümü (5.2.3) olabilir ilk Bildiricisi başladığı bir bildiri farksız bir (.Bu gibi durumlarda deyimi bir bildirimdir.

8.2 Belirsizlik çözünürlük [malzeme.ambig.res]

1Belirsizlik arasında bir benzerlik doğan tarzı fonksiyonu döküm ve beyan 6.8 sözü de bu bağlamda ortaya çıkabilir bir beyan. Bu bağlamda, seçim fonksiyonu arasında parantez gereksiz bir dizi bildirimi parametre etrafında adı ve işlevi tarzı bir oyuncu kadrosu ile bir nesne bildirimi başlatıcı. Sadece belirsizlikleri 6.8, olarak belirttiğim gibi çözünürlük içino muhtemelen olabilir inşa düşünün beyannamesi. [ Not: Bir bildiri açıkça olabilir = bir tarafından nonfunction tarzı bir döküm tarafından, göstermek için disambiguated başlatma veya gereksiz parantez kaldırarak parametre adı. —son not ] [ Örnek:

struct S {
    S(int);
};

void foo(double a) {
    S w(int(a));  // function declaration
    S x(int());   // function declaration
    S y((int)a);  // object declaration
    S z = int(a); // object declaration
}

uç bir örnek ]

Bu ünlü bir örnek ** 66, adı Effective STL kitabını: Madde 6'da Scott Meyers tarafından popüler

ifstream dataFile("ints.dat");
list<int> data(istream_iterator<int>(dataFile), // warning! this doesn't do
               istream_iterator<int>());        // what you think it does

Bu list<int> olan bir işlevi, data bildirir. Bu veri işlevi iki parametre alır:

  • İlk parametre dataFile olarak adlandırılır. Bu tür istream_iterator<int>. Bu dataFile parantez içine gereksiz ve göz ardı edilir.
  • İkinci parametre adı yok. Türünün işlevi ayırdığınız için işaretçi. hiçbir şey ve istream_iterator<int> bir dönüyor.

İlk fonksiyon argüman etrafında yerleştirerek ekstra parantez (ikinci bağımsız değişkeni parantez içine yasadışı) belirsizlik çözer

list<int> data((istream_iterator<int>(dataFile)), // note new parens
                istream_iterator<int>());          // around first argument
                                                  // to list's constructor

C 11-başlatıcı hazırla yan adım çok bağlamda bu tür ayrıştırma sorunları sağlayan sözdizimi vardır.

decltype ifadelerde Deducing referenceness

auto yazın aksine kesintinin, decltype referenceness (lvalue ve rvalue başvurular) indirilmeli sağlar. Kurallar decltype(e) decltype((e)) ifadeleri ayırt:

7.1.6.2 Basit tür belirteçleri [malzeme.yazın.basit]

Bir ifade İçin 4 e,türü decltype(e) ile gösterilirolarak tanımlanır şöyle:

— eğer e unparenthesized kimliği ifade ya da bir. unparenthesized sınıf üyesi erişim (5.2.5), decltype(e) türüdür varlık e tarafından isimlendirilmiş. Eğer böyle bir varlık varsa, ya da e isimler a aşırı yüklenmiş fonksiyonlar kümesi, program kötü oluşur;

— aksi takdirde, eğer e xvalue, decltype(e) T e; türü olduğu T&&

— eğer e bir lvalue, aksi takdirde 46 ** T türü T&, e;

— aksi takdirde, decltype(e) e türüdür.

Bu işlenen decltype belirleyicisi unevaluated bir işlenen (Madde 5). [ Örnek:

const int&& foo();
int i;
struct A { double x; };
const A* a = new A();
decltype(foo()) x1 = 0;   // type is const int&&
decltype(i) x2;           // type is int
decltype(a->x) x3;        // type is double
decltype((a->x)) x4 = x3; // type is const double&

uç örnek ] [ Not: belirleme türlerini içeren kuralları decltype(auto) 7.1.6.4 belirtilmiştir. —son not ]

decltype(auto) kuralları başlatılıyor ifadenin OLUŞTURDUĞU ekstra parantez için de benzer bir anlamı var. İşte C FAQ this related Q&A bir örnek

decltype(auto) look_up_a_string_1() { auto str = lookup1(); return str; }  //A
decltype(auto) look_up_a_string_2() { auto str = lookup1(); return(str); } //B

İlk döner string ikinci döndürür yerel değişken için bir referans olan string &, str.

Basit önlenmesi ile ilgili hataları makro

Aşağıda C dili uygun ile ilişkilerinde ön işlemci makroları ile inceliklerini, bir dizi var

  • kullanarak parantez etrafında makro parametreleri içinde makro tanımı #define TIMES(A, B) (A) * (B); önlemek için istenmeyen işleç önceliği (örneğin TIMES(1 2, 2 1) hangi sayıları 9 olur ama verim 6 olmadan parantez etrafında (A) (B)
  • makro değişkenleri içinde virgül olan parantezler kullanarak: aksi takdirde derleme olmaz assert((std::is_same<int, int>::value));
  • dahil başlıklarında makro genişleme karşı korumak için bir fonksiyon etrafında parantez kullanarak: (min)(a, b) (ADL devre dışı bırakma, istenmeyen yan etki)

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • picster

    picster

    20 NİSAN 2006
  • Tylerron

    Tylerron

    6 AĞUSTOS 2006
  • Vsauce

    Vsauce

    30 Temmuz 2007