IT TIP

정적 const float가 허용되지 않는 이유는 무엇입니까?

itqueen 2020. 11. 23. 20:46
반응형

정적 const float가 허용되지 않는 이유는 무엇입니까?


본질적으로 내 응용 프로그램을 통해 사용되는 일련의 상수 정의를 보유하는 클래스가 있습니다. 어떤 이유로 longs는 컴파일되지만 floats는 수행하지 않습니다.

class MY_CONSTS
{
public :
    static const long   LONG_CONST = 1;      // Compiles 
    static const float FLOAT_CONST = 0.001f; // C2864
};

다음 오류를 제공합니다.

1>c:\projects\myproject\Constant_definitions.h(71) : error C2864: 'MY_CONSTS::FLOAT_CONST' : only static const integral data members can be initialized within a class

내가 뭔가를 놓치고 있습니까?


실제 질문에 답하기 위해 "표준이 그렇게 말하고 있기 때문에".

정적, 상수, 정수 유형 (열거 형 포함)의 변수 만 클래스 선언 내에서 초기화 할 수 있습니다. 컴파일러가 float의 인라인 초기화를 지원하는 경우 확장입니다. 다른 사람들이 지적했듯이 정적, 상수, 비 정적 변수를 처리하는 방법은 클래스의 해당 소스 파일 (헤더가 아님)에서 변수를 정의하고 초기화하는 것입니다.

C ++ 표준 섹션 9.2 "클래스 멤버"항목 4 :

부재-선언자가 포함 할 수있는 일정한 이니셜 이 CONST 일체형 또는 CONST 열거 형의 고정 부재 (94)를 선언 한 경우에만, 9.4.2 참조.

섹션 9.4.2 "정적 데이터 멤버"항목 2 :

정적 데이터 멤버가 const 정수 또는 const 열거 형인 경우 클래스 정의의 선언 은 정수 상수 식 (5.19)이 될 상수 초기화 프로그램지정할 수 있습니다 . 이 경우 멤버는 정수 상수 식에 나타날 수 있습니다. 멤버는 프로그램에서 사용되는 경우 네임 스페이스 범위에서 정의되어야하며 네임 스페이스 범위 정의에는 이니셜 라이저가 포함되지 않아야합니다 .


cpp 파일 중 하나의 본문에서 초기화해야합니다.

class MY_CONSTS
{
public :
    static const long   LONG_CONST = 1;      // Compiles 
    static const float FLOAT_CONST;
};

const float MY_CONSTS::FLOAT_CONST = 0.001f;

Stroustrup의 설명을 참조하십시오 . 관련 인용문 :

클래스는 일반적으로 헤더 파일에서 선언되고 헤더 파일은 일반적으로 많은 변환 단위에 포함됩니다. 그러나 복잡한 링커 규칙을 피하기 위해 C ++에서는 모든 개체에 고유 한 정의가 있어야합니다. C ++에서 객체로 메모리에 저장해야하는 엔티티의 클래스 내 정의를 허용하면 해당 규칙이 깨집니다. C ++의 디자인 트레이드 오프에 대한 설명은 D & E를 참조하십시오.


다른 사람들이 제공 한 표준 문구의 근거는 템플릿 인수가 부동 소수점 숫자가 될 수없는 것과 동일합니다. 일관된 결과를 얻으려면 컴파일러가 컴파일 시간에 수행되는 것과 동일한 평가를 구현해야하며 이는 교차 컴파일러와 프로그램이 반올림 모드로 재생되는 경우 복잡 할 수 있습니다.

메모리에서 C ++ 0X에서 상수 표현식의 개념이 확장되어 코드가 유효합니다 (그러나 부동 소수점 상수 표현식의 결과로 지정되지 않은 것은 런타임 또는 컴파일 시간에 평가할 때 동일합니다.) ).


는 어때:

class MY_CONSTS
{
public :
    static const long   LONG_CONST;
    static const float FLOAT_CONST;
};

const long MY_CONSTS::LONG_CONST = 1;
const float MY_CONSTS::FLOAT_CONST = 0.001f;

(하지만이 특정한 경우에 대해 설명 할 수는 없지만 ...)


표준 9.4.2 / 4에서

정적 데이터 멤버가 const 정수 또는 const 열거 형인 경우 클래스 정의의 선언은 정수 상수 식 (5.19)이 될 상수 초기화 프로그램을 지정할 수 있습니다. 이 경우 멤버는 정수 상수 식에 나타날 수 있습니다. 멤버는 프로그램에서 사용되는 경우 네임 스페이스 범위에서 정의되어야하며 네임 스페이스 범위 정의에는 이니셜 라이저가 포함되지 않아야합니다.

그리고 5.19 / 1 :

In several places, C + + requires expressions that evaluate to an integral or enumeration constant: as array bounds (8.3.4, 5.3.4), as case expressions (6.4.2), as bit-field lengths (9.6), as enumerator initializers (7.2), as static member initializers (9.4.2), and as integral or enumeration non-type template arguments (14.3). constant-expression: conditional-expression An integral constant-expression can involve only literals (2.13), enumerators, const variables or static data members of integral or enumeration types initialized with constant expressions (8.5), non-type template parameters of integral or enumeration types, and sizeof expressions. Floating literals (2.13.3) can appear only if they are cast to integral or enumeration types. Only type conversions to integral or enumeration types can be used. In particular, except in sizeof expressions, functions, class objects, pointers, or references shall not

참고URL : https://stackoverflow.com/questions/2454019/why-arent-static-const-floats-allowed

반응형