2010-10-28 11 views
12

Mam następującą funkcjęprzechodzącą ciąg dosłownego do funkcji, która pobiera std :: string &

void AddNodeValue(XMLNode& node, std::string& value); 

chcę użyć go tak:

document.AddNodeValue(modvalue,"modvalue"); 

i kompilator narzeka:

error C2664: 'void XML::XMLDocument::AddNodeValue(XML::XMLNode &,std::string &)' : cannot convert parameter 2 from 'const char [9]' to 'std::string &' 
     A reference that is not to 'const' cannot be bound to a non-lvalue 

Nie rozumiem, dlaczego tak się dzieje?

Compiler: VS2003

Odpowiedz

23

Twoja funkcja musi podjąć const std::string&, aby używać go w taki sposób.

C++ ma regułę, że rwartość (w twoim przypadku tymczasowy std::string, który jest tworzony z literału ciągu znaków) może być związany z odniesieniem do stałej, ale nie odwołaniem do stałej.

Z tego, co wiem, to ograniczenie nie wynika z żadnego podstawowego problemu z wdrażaniem, ponieważ wartości tymczasowe mogą być modyfikowane w inny sposób na. Ale zakłada się, że funkcja, która przyjmuje odwołanie bezwzględne, robi to, ponieważ jej głównym celem jest modyfikowanie tego argumentu. Zazwyczaj nie ma większego sensu, aby zrobić to tymczasowo, więc ewentualne zakazywanie błędów wykrywa o wiele więcej, niż uniemożliwia ludziom robienie czegoś wartościowego. W każdym razie nie wszystkie rvalues ​​są tymczasowe: niektóre są literałami, których naprawdę nie można zmodyfikować.

Jeśli nie można zmienić AddNodeValue funkcji, to można obejść:

std::string valstr("modvalue"); 
document.AddNodeValue(modvalue, valstr); 
// valstr might have changed, check the documentation of AddNodeValue 
+0

Ograniczenie zasadzie istnieje egzekwować semantykę referencyjnych. Odniesienie należy stosować w przypadku obiektów ważnych i trwałych. Oczywiście możesz utworzyć nieprawidłowy odnośnik, zwracając odwołanie do wartości lokalnej, ale jest to błąd semantyczny. –

+1

@Let_Me_Be: right (zakładając, że przez "reference" masz na myśli "non const reference" - oczywiście referencje const nie powinny być używane tylko z trwałymi obiektami). Następne pytanie brzmi: * dlaczego * odniesienia nie-const mają być używane z ważnymi i trwałymi obiektami, a AFAIK to dlatego, że zwykle nie ma sensu modyfikowanie obiektów, które nie są. C++ 0x zapewnia nowy rodzaj odniesienia dla obiektów, które są poprawne, ale nie trwałe, co jest dobre na takie okazje, kiedy ma sens modyfikowanie takich obiektów. –

+0

Tak, C++ 0x udostępnia odniesienia do wartości l. Cały punkt odniesienia (wewnętrznie nadal jest wskaźnikiem) jest taki, że jest mocno ograniczony (przez przywiązanie do jakiegoś istniejącego obiektu, nie-zerowy, itd.). Dzięki temu kompilator może zapewnić znacznie bardziej interesujące optymalizacje. –

Powiązane problemy