Wprowadzenie
constexpr
nie został wprowadzony jako sposób poinformowania implementacji, że coś można ocenić w kontekście, który wymaga stałej ekspresji ; implementacje zgodne były w stanie to udowodnić przed C ++ 11.
Coś, czego implementacja nie może udowodnić, jest intencją określonego fragmentu kodu:
- Co deweloper chce wyrazić za pomocą tego podmiotu?
- Czy powinniśmy ślepo pozwolić, aby kod był używany w wyrażeniu stałym , tylko dlatego, że tak się dzieje?
Czym byłby świat bez constexpr
?
Załóżmy, że tworzysz bibliotekę i zdajesz sobie sprawę, że chcesz być w stanie obliczyć sumę każdej liczby całkowitej w przedziale (0,N]
.
int f (int n) {
return n > 0 ? n + f (n-1) : n;
}
Brak zamiaru
Kompilator może łatwo udowodnić, że powyższą funkcję można wywołać w wyrażeniu stałym jeśli przekazany argument jest znany podczas tłumaczenia; ale nie zadeklarowaliście tego jako zamiaru - tak się po prostu stało.
Teraz pojawia się ktoś inny, czyta twoją funkcję, wykonuje taką samą analizę jak kompilator; „ Och, ta funkcja nadaje się do wyrażenia ciągłego!” i zapisuje następujący fragment kodu.
T arr[f(10)]; // freakin' magic
Optymalizacja
Ty, jako „niesamowity” programista bibliotek, decydujesz, że f
powinieneś buforować wynik podczas wywoływania; kto chciałby ciągle obliczać ten sam zestaw wartości?
int func (int n) {
static std::map<int, int> _cached;
if (_cached.find (n) == _cached.end ())
_cached[n] = n > 0 ? n + func (n-1) : n;
return _cached[n];
}
Wynik
Wprowadzając swoją głupią optymalizację, po prostu przerwałeś każde użycie funkcji, które zdarzyło się w kontekście ciągłego wyrażania wymagane było .
Nigdy nie obiecałeś, że funkcja będzie użyteczna w ciągłym wyrażaniu i bez constexpr
niej nie byłoby sposobu na zapewnienie takiej obietnicy.
Dlaczego więc potrzebujemy constexpr
?
Podstawowym zastosowaniem constexpr jest deklarowanie zamiaru .
Jeśli jednostka nie jest oznaczona jako constexpr
- nigdy nie była przeznaczona do użycia w wyrażeniu stałym ; a nawet jeśli tak jest, polegamy na kompilatorze w diagnozowaniu takiego kontekstu (ponieważ nie uwzględnia on naszych zamiarów).
constexpr
? Jeśli tak, widzę użycie.