Mam klasy z static const
członków, że jestem inicjowanie wewnątrz deklaracji klasy:W jaki sposób in statyczna inicjalizacja statyczna floata różni się od int w C++?
#include <iostream>
class Foo
{
public:
static const int i = 9;
static const float f = 2.9999;
};
int main()
{
std::cout << Foo::i << std::endl;
std::cout << Foo::f << std::endl;
return 0;
}
Kiedy skompilowane z GCC 4.8.2 z opcją --std=c++11
, daje ten błąd kompilacji:
foo.cpp:7:32: error: ‘constexpr’ needed for in-class initialization of static data member ‘const float Foo::f’ of non-integral type [-fpermissive]
static const float f = 2.9999;
^
Jak wskazuje komunikat, błąd zniknie, jeśli linia zostanie zmieniona na static constexpr float f = 2.9999;
.
Dlaczego in statyczna inicjalizacja statyczna zmiennej zmiennoprzecinkowej może różnić się od zmiennej całkowej? Czy nie są one po prostu wartością o określonej wielkości (liczba bajtów), która jest kopiowana (jak makro) lub do której odnosi się wskaźnik?
Niektóre starsze odpowiedzi na podobne (nie takie same) pytania na temat SO wskazują, że dzieje się tak dlatego, że wyrażenia zmiennoprzecinkowe mogą dawać różne wyniki między kompilowaną maszyną a maszyną wykonawczą (przy założeniu scenariusza krzyżowego kompilacji).
Jednakże:
powyższy kod przypisuje wartość bezpośrednio, nie ma arytmetyczna operacja musi być wykonana, aby obliczyć wartość
mogą istnieć różne wyniki dla wyrażeń całkowych też od jego wyniki niedomiaru i przepełnienia nie są jednoznacznie zdefiniowane na różnych architekturach.
Wreszcie, co za magia
constexpr
zrobić tutaj, że nie ma tegoconst
? Dlaczego język nie działa po , gdy jest używany? To znaczy, dlaczego innego słowa kluczowego, gdy następujące stwierdzenia działa dobrze, jak C++ kod poza klasą w każdym razie:const int i = 9; const float f = 2.9999;
Nie jestem do końca pewien, dlaczego, ale przed C++ 11 działało tylko dla typów integralnych. C++ 11 zezwala na dowolny typ literalny za pośrednictwem 'constexpr'. – chris
@chris: Dlaczego C++ 11 nie robi po prostu tego, co constexpr robi dla tej instrukcji i robi to dla samej const? Dlaczego należy wymagać od użytkownika użycia nowego słowa kluczowego? –
Czy próbowałeś 'static const float f = 2.9999f'? –