2014-09-23 43 views
30

Aşağıdaki kod, char için örtük dönüştürme nedeniyle derlenmiştir. Neden beklediğim tek örtülü dönüşümden (ve başarısızlığa uğramayı beklediğinden) neden char const* - size_t arasında olduğundan emin değilim.C++ beklenmedik implict dönüşümü

#include <cstddef> 

struct foo 
{ 
    int operator[](size_t i) const { return 1; } 
    operator char() const { return 'a'; } 
}; 

int main() 
{ 
    foo f; 
    f["hello"]; // compilation error desired here 
} 

Burada örtülü dönüştürme, bunun derlenmesine olanak veren nedir? operator char'u kaldırırsam veya explicit yapsam, derleme istenen konumda başarısız olur.

Bu kodun gerçekten çıkarıldığı sınıf, hem örtük dönüşüme hem de operator[]'a gereksinim duyar. Yani, dönüşümü açık hale getirmeden davranışı engelleyebileceğim bir yol var mı?

+1

eklemeyi denediniz: böylece daha iyi, arge değeri (bir göstericinin değeri) [] aşırı ederken dikkatli olun ve varsa Aslında, orada üst sınır için kontrol edin; Aslında endeks değeri al olurdu özel bir işleç [] (char const *) '? –

cevap

34

Satır derlemesinin nedeni, örtük dönüştürme ile olarak yorumlanabilir ve bu da *(('a')+("hello"));'un yazılmasıyla aynıdır. Standard

Alıntı:

5.2.1 Altsimgeleme:

... sentezleme E1 [E2] ((E 1) + * için (tanımı gereği) aynıdır (E2) silinen gibi) ...

dönüşüm operatörü açık yapmadan en kolay çözüm kusurlu simge operatöre bildirmek için:

struct foo 
{ 
    operator char() const { return 'a'; } 
    int operator[](size_t i) const { return 1; } 

    // prevent accidental use of foo["hello"] 
    int operator[](char const*) const = delete; 
}; 
+3

... ve "* (E2 + E1)' ve "E2 [E1]' ile eşdeğerdir. Ben buna bariz demedim ... –

+7

@UlrichEckhardt, yes, '" merhaba "[0]', 0 ["merhaba"] 'ile eşdeğerdir. – imreal

+4

Gerçekten de belli değil. C++. C++ tuzakları ve tuzaklarla dolu kitaplar var. – Jerry101

0
f["hello"]; 

, f.operator [] (indeks) 'e çevirir; burada dizin, "merhaba" u işaret eden işaretçinin değeridir. Sizin durumunuzda, operatör [] (size_t i) çağırır. Böylece, derleyici şikayet etmediği kesinlikle tamam.

char *c = "hello"; // c is a pointer 
f[c]; // ok 
+0

Ummm, bu tamamen yanlış ve yanıltıcıdır A 'char * 'bir' size_t 'dolaylı olarak dönüştürülebilir değildir, bu yüzden' foo :: operator [] 'hiçbir zaman seçili değildir. '' '' 'karakterine dönüşür, böylece '' merhaba '' ile aynıdır, '' merhaba '' ['a']' ile aynıdır. Lütfen gönderilmeden önce kabul edilen cevaba bir göz atın. – marack