2013-07-11 26 views
10

Referans için bir dönüşüm operatörüne sahip olursam, bu operatör bool numaralı bir dönüşüme göre öncelik kazanacaktır. Bu neden oluyor ve nasıl düzeltebilirim?Dönüştürme işlemi neden boole dönüştürmeyi engelliyor?

(. Bu konularda, ben GCC 4.5 kullanıyorum ben aynı davranış GCC-4.7.2 ile bulunduğunu ideone doğrulandı.)

aşağıdaki varsayalım: Sonra

class B { 
protected: 
    const int a_; 
    int b_; 
    B (int b, int a) : a_(a), b_(b) {} 
public: 
    operator bool() const { return b_ == a_; } 
}; 

class D1 : public B { 
public: 
    D1 (int b = 0, int a = 0) : B(b, a) {} 
    operator int() const { return b_; } 
}; 

class D2 : public B { 
public: 
    D2 (int b = 0, int a = 0) : B(b, a) {} 
    operator int &() { return b_; } 
}; 

, onlar böyle basit bir programda kullanılan kazanırlar:

int main() { 
    if (D1 d1a = D1('a', 'a')) std::cout << "d1a\n"; 
    if (D1 d1b = D1('b', 'a')) std::cout << "d1b\n"; 
    if (D2 d2a = D2('a', 'a')) std::cout << "d2a\n"; 
    if (D2 d2b = D2('b', 'a')) std::cout << "d2b\n"; 
    return 0; 
} 

Bu programın çıktısı:

d1a 
d2a 
d2b 

d1b'un çıktıda olmadığını unutmayın; bu, bool dönüşümünün D1 için beklediğim şekilde çalıştığını gösterir. Ancak, D2 için, referans türüne dönüşüm, bool dönüşümüne göre öncelikli görünüyor. Bu neden oldu? if denetiminde bool dönüşümünün öncelik kazanmasına izin vermek için D2 yapmam gereken basit bir değişiklik var mı?

Şu anda, D1 kullanıyorum ve bir başvurunun davranışını gerçekleştirmek için ona bir atama işleci ekliyorum.

+0

evet Eh, muhtemelen ben katılıyorum Bunu kendim görebilmiş olmalıyım, ama kötü bir gün geçirmemi engellemek dışında, aşağı oy için daha önemli bir neden var mı? – jxh

cevap

9

tarafından, bu int& ile ilgisi olup olmadığını ben 4th yerine yalnızca d1a ve çıktıda d2a var, bu const -lık meselesi Bir D2, bir const D2 değil, bu yüzden const olmayan dönüşüm operatörü daha iyi bir uyumdur. Eğer

operator const int &() const { return b_; } 

olarak yazarsanız size, beklenen davranışı elde http://ideone.com/vPPPYV göreceksiniz.

Not Eğer nesnelerin const sürümlerini kullanıyorsanız operator const int& bile engel olmaz ki şu satırları hala beklenen davranışlara neden olur (http://ideone.com/DTE0xH bakınız):

if (const D1 d1a = D1('a', 'a')) std::cout << "d1a\n"; 
if (const D1 d1b = D1('b', 'a')) std::cout << "d1b\n"; 
if (const D2 d2a = D2('a', 'a')) std::cout << "d2a\n"; 
if (const D2 d2b = D2('b', 'a')) std::cout << "d2b\n"; 
+1

Teşekkürler, bu benim için açıklıyor. Düzeltme, "bool" dönüşüm işlecinin "olmayan" bir sürümünü eklemektir. – jxh

+1

Fantastik cevap! – Antonio

1

Bu

D1 d1a = D1('a', 'a'); 
D1 d1b = D1('b', 'a'); 
D2 d2a = D2('a', 'a'); 
D2 d2b = D2('b', 'a'); 
if (d1a) std::cout << "d1a\n"; 
if (d1b) std::cout << "d1b\n"; 
if (d2a) std::cout << "d2a\n"; 
if (d2b) std::cout << "d2b\n"; 

baskılar benim için

d1a 
d2a

.

You have her iki durumda da aynı adı kullanmayın ne olur

if (D2 d2a = D2('a', 'a')) std::cout << "d2a\n"; 
if (D2 d2a = D2('b', 'a')) std::cout << "d2b\n"; 

?

operator bool() const { return b_ == a_; } 
       /* ^^^^^ */ 
       /* vvvvv */ 
operator int &() { return b_; } 

d2a geçerli: Aslında

if (D2 d2b = D2('b', 'a')) std::cout << "d2b\n"; 
+0

Sonuç aynıdır (bkz. Http://ideone.com/CpPXZS). Soruyu güncelleyeceğim. – jxh

+0

Tamam, peki ... MSVC++ 11 (VS12) 'd2b' yazdırmıyor. – Pixelchemist

+0

+1, GCC-C++ ve MSVC++ arasındaki davranış farkını ilginç buluyorum. – jxh

İlgili konular