Nice programing

C ++의 클래스 선언 내에서 const 멤버 초기화

nicepro 2020. 10. 28. 21:01
반응형

C ++의 클래스 선언 내에서 const 멤버 초기화


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 #에서 가능한 것처럼 클래스 선언 내에서 상수를 초기화하는 방법이 있습니까?

최신 정보

staticg ++의 클래스 선언 내에서 이러한 상수를 초기화 할 수 있기 때문에 키워드를 사용 했습니다. 선언 여부에 관계없이 클래스 선언에서 상수를 초기화하는 방법이 필요합니다 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모든 클래스 인스턴스의 멤버 는 컴파일러 생성 생성자 X5의해 초기화되고 f멤버는로 초기화됩니다 3.12. static const데이터 부재 j를 초기화 42하고, static constexpr데이터 부재 g로 초기화된다 9.5.

이후 floatdouble통합 또는 열거 유형이 아닌, 같은 회원이어야합니다 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

for the details on the available macros.

With gnu, you could also stick with using 'const' everywhere and then compile with the -fpermissive flag, but that gives warnings and I like my stuff to compile cleanly.

Not great, because it's specific to gnu compilers, butI suspect you could do similar with other compilers.

참고URL : https://stackoverflow.com/questions/9141950/initializing-const-member-within-class-declaration-in-c

반응형