2014-09-24 15 views
13

Słowo kluczowe constexpr zostało wprowadzone w języku C++ 11, ponieważ (jak sądzę) była to odpowiednia idea "wyrażeń stałych". Jednak koncepcja ta została w sposób dorozumiany przedstawić w C++ 98/C++ 03, ponieważ deklaracja tablicy wymaga stałej ekspresji:"Wyrażenia stałe" przed C++ 11

// valid: 
int a[sizeof(int)]; 
int b[3+7]; 
int c[13/4]; 
const int n = 3; 
int d[n]; 
// invalid: 
int m = 4; 
int e[m]; 

Istnieją inne wyrażenia „stałe”, czyli wyrażenia, które mogą być (i/lub musi być) oceniane podczas kompilacji; jednym z przykładów są argumenty szablonu.

W przypadku wersji przed C++ 11 czy istnieją następujące standardy C++ 98/03?

  • Pełną listę składniowych konstrukcjach wymagających stałych wyrażeń (np deklaracji tablicy i dawałaby szablonu)
  • Reguły tego typu stałych wyrażeń (prawdopodobnie to będzie tylko odwzorowaniem z elementów w powyższej listy do ich definicji w standardzie)
+0

Zaczekaj minutę !: "deklaracje tablicowe wymagają wyrażenia * stałej *"? Dlaczego to mówisz? – wallyk

+4

@ Wallyk Bo to prawda. –

+1

@KonradRudolph to dar rozszerzeń kompilatorów, to niesamowite, ilu programistów C++ o tym nie wie. –

Odpowiedz

12

constexpr i stałe wyrażenia są powiązane w tym constexpr mówi nam, że zmienna lub funkcja może być używana gdzie stała ekspresja może być używana. To co cppreference nam powiedzieć:

constexpr specifier deklaruje, że jest możliwe, aby ocenić wartość funkcji lub zmiennej w czasie kompilacji. Takie zmienne i funkcje mogą być następnie użyte tam, gdzie dopuszczalna jest tylko stała czasowa kompilacji .

Constant expresions były obecne przed C++ 11 i zasady rządzące stale wyrażeń pre C++ 11 objęte są w tym samym miejscu w C++03 draft standard (to najwcześniej projekt publicznego najbliżej C + +03) jako draft C++11 standard która jest sekcja 5.19stałe wyrażenia, cppreference ma dobre podsumowanie na ten temat w Constant expressions stronie, ale jest nastawiona C++ 11 i C++ 14 i trudno powiedzieć, co stosuje pre C++ 11.

średnia wstępnie C++ 11 list, gdzie wymagana jest stałym wyrażeniem, w ustępie pierwszym 5.19 i wygląda kompletna:

W kilku miejscach, C++ wymaga wyrażenia, które oceniają na integralnej lub wyliczenie stała: jako granica macierzy (8.3.4, 5.3.4), jako wyrażenia przypadku (6.4.2), jako długości pól bitowych (9.6), jako inicjatory modułów wykonawczych (7.2), jako inicjatory członów statycznych (9.4.2) , oraz jako integralne lub wyliczeniowe argumenty wzorców non-type (14.3).

reszta ust mówi:

Integralną stałej wyrażenie może dotyczyć tylko literały z typów arytmetycznych (2,13, 3,9.1), moduły wyliczające, nieulotne zmienne zmienne lub statyczne elementy danych typu całkowego lub wyliczeniowego inicjalizowane za pomocą wyrażeń stałych (8.5), szablonów nietypowych parametry typów całkowych lub wyliczeniowych oraz wyrażenia sizeof. Pływające znaki literowe (2.13.3) mogą być wyświetlane tylko wtedy, gdy są rzucane na typy całkowe lub wyliczeniowe . Można stosować tylko konwersje do typów integralnych lub . W szczególności, z wyjątkiem wymiarów wyrażeń, funkcji, obiektów klasy, wskaźników lub odniesień nie należy używać, a przypisanie, inkrementowanie, dekrementacja, wywoływanie funkcji lub operatorów przecinków nie są używane.

, a następnie 5 więcej akapitów, które zawierają listę dalszych wymagań.

W C++ 11 znajduje się lista miejsc, w których wyrażenia stałe mogą być używane w paragrafie , ale nie wyjaśniają, gdzie są wymagane. Prawdopodobnie trzeba szukać terminu stałej ekspresji znaleźć wszystkie miejsca, gdzie jest to wymagane i zwykle nie będzie wyrażenie podobne do:

powinny być stałym wyrażeniem

musi być, który jest ważnym terminem, ponieważ naruszenie wymogu sprawia, że ​​program jest źle sformułowany.

Alternatywnie można użyć Annex AGrammar podsumowanie i szukać stałej ekspresji i które powinny obejmować wszystkie miejsca w gramatyce, gdzie wymagany jest stałym wyrażeniem, np

enumerator = constant-expression 

Przypis:

  1. Ta answer to Where do I find the current C or C++ standard documents? ma pełną listę projektów standardów. Niestety najbliższa dostępna publicznie pochodzi z wczesnego 2005. Wcześniejsze wersje wymagają uwierzytelnienia. O ile mi wiadomo, sekcja 5.19 niewiele się zmieniła.
+0

Standardowy projekt, do którego odnośnik jest z 2005 r. ... jest tak naprawdę dla 'C++ 03'? –

+0

@ KyleStrand dostępny jest najwcześniejszy publiczny projekt standardu, można znaleźć pełną listę wersji roboczych dostępnych dla wszystkich [tutaj] (http://stackoverflow.com/questions/81656/where-do-i-find-the-current -c-or-c-dokumenty standardowe). –