PHP 및 C #에서 상수는 선언 된대로 초기화 할 수 있습니다.
class Calendar3
{
const int value1 = 12;
const double value2 = 0.001;
}
두 수학 벡터를 비교하기 위해 다른 클래스와 함께 사용되는 펑터에 대한 다음 C ++ 선언이 있습니다.
struct equal_vec
{
bool operator() (const Vector3D& a, const Vector3D& b) const
{
Vector3D dist = b - a;
return ( dist.length2() <= tolerance );
}
static const float tolerance = 0.001;
};
이 코드는 g ++에서 문제없이 컴파일되었습니다. 이제 C ++ 0x 모드 (-std = c ++ 0x)에서 g ++ 컴파일러는 오류 메시지를 출력합니다.
오류 : 정수가 아닌 유형의 정적 데이터 멤버 ‘tolerance’의 클래스 내 초기화에 ‘constexpr’이 필요합니다.
static const
클래스 정의 외부 에서이 멤버를 정의하고 초기화 할 수 있다는 것을 알고 있습니다 . 또한 비 정적 상수 데이터 멤버는 생성자의 이니셜 라이저 목록에서 초기화 할 수 있습니다.
그러나 PHP 또는 C #에서 가능한 것처럼 클래스 선언 내에서 상수를 초기화하는 방법이 있습니까?
최신 정보
static
g ++의 클래스 선언 내에서 이러한 상수를 초기화 할 수 있기 때문에 키워드를 사용 했습니다. 선언 여부에 관계없이 클래스 선언에서 상수를 초기화하는 방법이 필요합니다 static
.
답변
C ++ 11에서 static
데이터가 아닌 멤버, static constexpr
데이터 멤버, static const
정수 또는 열거 형 데이터 멤버는 클래스 선언에서 초기화 될 수 있습니다. 예 :
struct X {
int i=5;
const float f=3.12f;
static const int j=42;
static constexpr float g=9.5f;
};
이 경우 i
모든 클래스 인스턴스의 멤버 는 컴파일러 생성 생성자 X
에 5
의해 초기화되고 f
멤버는로 초기화됩니다 3.12
. static const
데이터 부재 j
를 초기화 42
하고, static constexpr
데이터 부재 g
로 초기화된다 9.5
.
이후 float
및 double
통합 또는 열거 유형이 아닌, 같은 회원이어야합니다 constexpr
, 또는 비 static
허용 할 클래스 정의의 초기화의 순서이다.
C ++ 11 이전에는 static const
정수 또는 열거 유형의 데이터 멤버 만 클래스 정의에 이니셜 라이저를 가질 수있었습니다.
답변
const int 유형 이외의 정적 멤버 변수를 초기화하는 것은 C ++ 11 이전의 표준 C ++가 아닙니다. gcc 컴파일러는 -pedantic
옵션 을 지정하지 않는 한 이에 대해 경고하지 않고 유용한 코드를 생성합니다 . 그러면 다음과 유사한 오류가 발생합니다.
const.cpp:3:36: error: floating-point literal cannot appear in a constant-expression
const.cpp:3:36: warning: ISO C++ forbids initialization of member constant ‘tolerance’ of non-integral type ‘const float’ [-pedantic]
그 이유는 C ++ 표준이 부동 소수점 구현 방법을 지정하지 않고 프로세서에 맡기기 때문입니다. 이 문제와 기타 제한 사항을 해결하기 위해 constexpr
도입되었습니다.
답변
예. constexpr
오류가 말한대로 키워드를 추가하십시오 .
답변
하나의 메서드에서만 필요한 경우 로컬에서 정적으로 선언 할 수 있습니다.
struct equal_vec
{
bool operator() (const Vector3D& a, const Vector3D& b) const
{
static const float tolerance = 0.001f;
Vector3D dist = b - a;
return ( dist.length2() <= tolerance );
}
};
답변
다른 버전의 g ++ (GNU C ++ 컴파일러)로 컴파일하려면 동일한 코드가 필요하기 때문에이 문제가 실제로 발생했습니다. 그래서 매크로를 사용하여 어떤 버전의 컴파일러가 사용되고 있는지 확인한 다음 그에 따라 조치를 취해야했습니다.
#if __GNUC__ > 5
#define GNU_CONST_STATIC_FLOAT_DECLARATION constexpr
#else
#define GNU_CONST_STATIC_FLOAT_DECLARATION const
#endif
GNU_CONST_STATIC_FLOAT_DECLARATION static double yugeNum=5.0;
이것은 g ++ 버전 6.0.0 이전의 모든 것에 ‘const’를 사용하고 g ++ 버전 6.0.0 이상에는 ‘constexpr’을 사용합니다. 솔직히 g ++ 버전 6.2.1까지이 사실을 알아 차리지 못했기 때문에 변경이 발생하는 버전에 대한 추측 입니다. 제대로하려면 g ++의 부 버전과 패치 번호를 확인해야 할 수도 있습니다.
https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html
사용 가능한 매크로에 대한 자세한 내용은
gnu를 사용하면 모든 곳에서 ‘const’를 사용하고 -fpermissive
플래그 로 컴파일 할 수 있지만 경고가 표시되고 내 항목이 깔끔하게 컴파일되는 것이 좋습니다.
그것은 gnu 컴파일러에 한정되어 있기 때문에 좋지는 않지만 다른 컴파일러와 비슷하게 할 수 있다고 생각합니다.