2012-02-08 17 views
6

Poniższy C++ jest nieważne, ponieważ zmienne referencyjne wymagają inicjatorów:Inicjowanie zmiennych referencyjnych z operatorem warunkowym

int& a; // illegal 
if (isfive) { 
    a = 5; 
} else { 
    a = 4; 
} 

jednak MSVC wydaje się, że to jest w porządku:

int& a = isfive ? 5 : 4; 

Oznacza to dla mnie, że MSVC traktuje operator warunkowy jak pojedyncze wyrażenie i nie rozwija go w instrukcję if-else.

Czy jest zawsze prawidłowe C++, aby zainicjować odniesienie za pomocą operatora warunkowego?

+0

Ciekawe, co się stanie, jeśli spróbujesz porównać to na poziomie zespołu ... – beta0x64

+3

Jak porównać na poziomie assemicznym, który kompiluje, i kod, który nie działa? –

+0

Co to robi? Proszę po złożeniu! :-) – Florian

Odpowiedz

5

MSVC ma niestandardowe "rozszerzenie". Co to znaczy, że pozwala na złamanie kodu. Jest dobry powód, dla którego jest to zabronione.

Należy również zauważyć, że

int& a = 5; 

nie jest legalne w standardowej C++ albo.

Ogólnie rzecz biorąc, możliwe jest zainicjowanie odwołania o wartości const z dowolnym wyrażeniem, które można przekonwertować na prawidłowy typ (w tym użycie operatora warunkowego). Prawidłowe jest zainicjowanie odwołania o numerze innym niż const z lwartością odpowiedniego typu, którą operator warunkowy ustala w określonych warunkach.

+1

Co wiesz, zadając to pytanie rozwiązałeś problem, którego nawet nie znałem. Dzięki! – Kai

0

Jest operatorem, częścią wyrażenia, a nie instrukcją. I nie można pozostawić referencji niezainicjowanej nawet przez krótki czas ;-)

3

Operator warunkowy jest wyrażeniem, a nie instrukcją. Całkiem dobrze jest zainicjować taki odnośnik. To trochę jak inicjowanie odwołania przez wywołanie funkcji.

Należy pamiętać, że odniesienie musi być const, jeśli wiążesz go z tymczasowymi (reguła, którą MSVC++ głupio ignoruje).

+0

* Zasadnie dobrze jest zainicjować odniesienie w ten sposób * tylko wtedy, gdy zignorujemy fakt, że nie można powiązać nieokreślonego odniesienia z wartością rwart ... (np. "Const int & r = isfive? 4: 5;' jest w porządku , ale 'int & r = isfive? 4: 5;' is not) –

+0

@ DavidRodríguez-dribeas tak, Dodałem notatkę o tym jakiś czas temu. –

2

Kod pan pisał nie skompilować z VC++ 2010:

Error 1 error C2440: 'inicjowanie': nie można przekonwertować z 'int' do 'int &'

Zmiana wiersz:

const int& a = isfive ? 5 : 4; 

powoduje, że kompilacja.

+0

Zakładam, że używasz opcji '/ Za' (wyłącz rozszerzenia językowe)? –

+0

@ BonVoigt: Nie. Wydaje się, że problem został rozwiązany: http://technet.microsoft.com/en-us/query/szywdw8k –

+0

Zastanawiam się, co to robi w TechNet zamiast MSDN. Nadal istnieje kilka powiązanych błędów, ale zadowolenie, że najbardziej typowy przypadek jest naprawiony. –

1

to nie jest OK

int& a = isfive ? 5 : 4; 

chyba zadeklarować odniesienia "a" jako const.

4

Operator potrójny nie rozwija się do konstrukcji if-else (nie w zależności od języka, implementacja może generować równoważne pliki binarne, ale na poziomie językowym są różne). Więc następujący kod jest ważny:

int four = 4, five = 5; 
int& r = condition? four : five; 

Oryginalny przykład w kwestii zależy od rozszerzenia Microsoft, który (niesłusznie) umożliwia wiązanie non-const odniesienia do wyrażenia rvalue.

Powiązane problemy