Czy jest jakiś odpowiednik, bloku inicjalizacyjnego (statycznego bądź instancyjnego) z Javy, który działby podobnie w C++? Prosty przykład. W Javie jeśli w jakiejś klasie chcę mieć stałą, której wartością jest powiedzmy suma dodatnich kwadratów od 0 do 10 to pisze się to tak:
class Foo {
static final int SQUARE;
static {
int sumOfSquare = 0;
for(int i = 1; i <= 10; i++) {
sumOfSquare += i * i;
}
SQUARE = sumOfSquare;
}
}
W C++ mamy constexpr
, dzięki któremu możemy obliczać wartości stałe w czasie kompilacji, a nawet obliczać takie stałe korzystając z funkcji (które jednak również muszą być zadeklarowane jako constexpr
). No i pomału zbliżamy się do rozwiązania problemu ale jest jedno ale.
Załóżmy, że w odpowiedniej klasie ale już w C++ chcę mieć to samo co powyżej w Javie. Mogę to napisać tak:
constexpr int computeSquare(int n) {
int sumOfSquare = 0;
for(int i = 1; i <= 10; i++) {
sumOfSquare += i * i;
}
return sumOfSquare;
}
class Foo {
static constexpr int SQUARE = computeSquare(10);
};
No i jest super, bo zostało to obliczone w czasie kompilacji. To co rozróżnia jednak ten przykład od powyższego w Javie jest to, że ja cały czas mam dostępną funkcję constexpr int computeSquare(int n)
, którą mogę wywoływać. A tego nie chcę. Widzę dwa rozwiązania:
- Mogę zostawić to tak jak jest, godząc się na większy kod wynikowy właśnie o tę funkcję.
- Mogę to obliczyć wcześniej na kartce i wstawić gotową obliczoną wartość i w ogóle nie korzystać z
constexpr
ale to był tylko przykład i przy bardziej skomplikowanym wyrażeniu obliczenia na kartce mogą potrwać wieki.
Więc pytanie jest takie: jak obliczyć w czasie kompilacji (o ile się da) skomplikowane wyrażenie i przypisać to do stałej ale tak, żeby nie mieć później dostępnej funkcji dzięki któremu obliczyło się owo stałą wartość? Czy można zrobić coś podobnego jak blok inicjalizacyjny w Javie?