>백엔드 개발 >C++ >템플릿 클래스의 정적 멤버 초기화가 다르게 동작하는 이유는 무엇입니까?

템플릿 클래스의 정적 멤버 초기화가 다르게 동작하는 이유는 무엇입니까?

DDD
DDD원래의
2024-10-28 08:57:02735검색

 Why Does Static Member Initialization in Templated Classes Behave Differently?

템플릿 클래스의 정적 멤버 초기화 복잡성

C에서 정적 멤버 초기화는 널리 사용되는 기술이지만 처리할 때 복잡해질 수 있습니다. 템플릿 클래스. 템플릿이 아닌 클래스에서는 중첩된 도우미 구조체를 초기화에 사용할 수 있지만 바깥쪽 클래스가 템플릿일 때는 이 접근 방식이 부족합니다.

다음의 간단한 예를 고려하세요.

<code class="cpp">struct A
{
    static std::string mA;
    static InitHelper mInit;

    static const std::string& getA() { return mA; }
};
std::string A::mA;
A::InitHelper A::mInit;


template<class T>
struct B
{
    static std::string mB;
    static InitHelper mInit;

    static const std::string& getB() { return mB; }
    static InitHelper& getHelper() { return mInit; }
};
template<class T>
std::string B<T>::mB;
template<class T>
typename B<T>::InitHelper B<T>::mInit;

int main()
{
    std::cout << "A = " << A::getA() << std::endl;

    // Comment/uncomment lines to observe different behaviors
    // std::cout << "B = " << B<int>::getB() << std::endl; // [1]
    // B<int>::getHelper(); // [2]
}</code>

예상 동작:

[1]이 주석 처리되지 않고 [2]가 주석 처리되면 B::mB가 "Hello, I'm B"로 초기화될 것으로 예상됩니다. . 그러나 이런 일은 발생하지 않습니다.

실제 동작:

  • [1]과 [2]의 댓글: 부작용 없음 발생합니다.
  • 주석 처리되지 않은 [1] 사용: B::getB()는 빈 문자열을 반환합니다.
  • [1] 및 [2 사용 ] 주석 처리되지 않음: B::mB가 올바르게 초기화되었습니다.
  • [1] 주석 처리됨 및 [2] 주석 처리 제거됨: 정적 초기화 중에 분할 오류가 발생합니다.

불일치 이유:

ISO/IEC C 2003 표준에 따르면 템플릿 멤버는 정의가 필요한 컨텍스트에서 참조될 때 암시적으로 인스턴스화됩니다. 존재하다. 그러나 정적 데이터 멤버 초기화(및 관련 부작용)는 정적 데이터 멤버가 명시적으로 사용되는 경우에만 발생합니다. 즉, 템플릿 멤버가 인스턴스화되지 않은 템플릿이나 전체 인스턴스화가 필요하지 않은 다른 컨텍스트에서만 참조되는 경우 해당 정적 데이터 멤버는 초기화되지 않습니다.

예제에서 B:: getB()는 B::mB가 존재해야 하지만 이는 정의(초기화 프로그램 포함)가 아닌 멤버 템플릿 선언의 인스턴스화만 강제합니다. 대조적으로, B::getHelper()는 참조를 반환하기 때문에 B::mInit 정의가 필요합니다.

해결책:

표준에서는 명시적으로 특수화된 클래스 템플릿 정적 데이터 멤버의 정의가 초기화 순서를 갖는 반면 다른 클래스 템플릿 정적 데이터 멤버의 정의는 순서 없는 초기화를 갖는 것을 금지합니다. 일관된 초기화 순서를 보장하려면 명시적인 특수화를 사용해야 합니다.

위 내용은 템플릿 클래스의 정적 멤버 초기화가 다르게 동작하는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.