Rzeczywiście ostateczna wersja C++ 11 nie umożliwia korzystania z list inicjalizujących po prawej stronie (lub lewej stronie, jeśli o to chodzi) operatora binarnego.
Po pierwsze, listy inicjalizacyjne nie są wyrażeniami zdefiniowanymi w §5 Standardu. Argumenty funkcji, jak również operatorów binarnych, muszą być generalnie wyrażeniami, a gramatyka dla wyrażeń zdefiniowanych w §5 nie zawiera składni dla listek inicjujących brace (tj. Czystych list inicjalizujących; zauważ, że nazwa_tabliczna następnie lista inicjująca nawias klamrowy, taka jak bar {2,5,"hello",7}
, jest wyrażeniem).
Aby móc użyć czystego inicjator listami Korzystnie, średnia definiuje różne wyjątków, które są przedstawione w poniższej (nienormatywnej) Uwaga:
§8.5.4/1 [...] Uwaga: Lista inicjalizacja może być stosowany
- jako inicjator w definicji zmiennej (8,5)
- jako inicjator w nowej ekspresji (5.3.4)
- w instrukcji return (6.6.3)
- w funkcji argumen t (5.2.2)
- jako indeks (5.2.1)
- jako argument do wywołania konstruktora (8.5, 5.2.3)
- jako inicjator dla niż statyczna składowa danych (9.2)
- w mEM inicjatora (12.6.2)
- po stronie prawej przydziału (5,17)
[...]
czwarty element powyżej wyraźnie umożliwia czysty initializer- list jako argumenty funkcji (dlatego działa operator<<(baz, {1, -2, "foo", 4, 5});
), piąty pozwala na to w wyrażeniach dolnych (np. jako argument z operator[]
, np. mymap[{2,5,"hello"}]
jest legalny), a ostatni element umożliwia im po prawej stronie przypisania (ale nie ogólne operatory binarne).
Jest ma takiego wyjątku dla operatorów binarnych jak +
, *
lub <<
, stąd nie można umieścić czystą listę initializer (to znaczy taki, który nie jest poprzedzony TypeName) po obu stronach z nich.
Co do przyczyn tego, A draft/discussion paper N2215 przez Stroustrup i Dos Reis od 2007 zapewnia wiele wgląd w wiele problemów z initializer listach w różnych kontekstach.W szczególności, istnieje sekcja operatorów binarnych (sekcja 6.2):
Rozważmy bardziej ogólnych zastosowań list initializer. Na przykład:
v = v+{3,4};
v = {6,7}+v;
Gdy weźmiemy pod uwagę operatorów jak cukier dla funkcji składniowej, naturalnie pod uwagę powyższą równowartość
v = operator+(v,{3,4});
v = operator+({6,7},v);
Jest więc naturalne, aby rozszerzyć stosowanie list initializer do wyrażeń. Istnieje wiele zastosowań, w których listy inicjalizatorów połączone z operatorami są zapisami "naturalnymi".
Jednak nie jest rzeczą trywialną napisanie gramatyki LR (1), która umożliwia dowolne korzystanie z list inicjalizujących. Blok zaczyna się również od {pozwalając, aby lista inicjalizatorów jako pierwsza (po lewej) jednostka wyrażenia prowadziłaby do chaosu w gramatyce.
To jest trywialne, aby umożliwić listy inicjalizatorów jako prawostronny operand operatorów dwójkowych, w indeksach i podobnych izolowanych częściach gramatyki. Prawdziwym problemem jest dopuszczenie ;a={1,2}+b;
jako instrukcji przypisania, bez zezwolenia na ;{1,2}+b;
. Podejrzewamy, że pozwalając inicjator wymienia jako prawą rękę, ale ani [sic] jako argumenty lewej ręki do większości operatorów jest zbyt dużo kludge, [...]
Innymi słowy, initializer-list nie są włączone po prawej stronie , ponieważ nie są włączone po lewej stronie: i nie są włączone po lewej stronie, ponieważ spowodowałoby to zbyt duże wyzwanie dla analizatorów składni.
Zastanawiam się, czy problem mógł zostać uproszczony przez wybranie innego symbolu zamiast nawiasów klamrowych dla składni listy inicjalizującej.
Ponieważ nie przeładowałeś 'operatora <<' do zrobienia 'initializer_list <>' na RHS ... Jakie jest twoje aktualne pytanie? – ildjarn
Miałem nadzieję, że jest to odpowiednik 'baz << bar {1, 2, 3, 4, 5};', ale wygląda na to, że nie ma żadnej konwersji. – mavam
Jeśli takie zachowanie chcesz, może powinieneś spróbować podać 'bar' nie-jawny konstruktor, który bierze pojedynczą' initializer_list <> '. – ildjarn