>  기사  >  백엔드 개발  >  중첩된 도우미 구조체를 사용하여 템플릿 기반 C 클래스의 정적 멤버를 어떻게 안정적으로 초기화할 수 있나요?

중첩된 도우미 구조체를 사용하여 템플릿 기반 C 클래스의 정적 멤버를 어떻게 안정적으로 초기화할 수 있나요?

Barbara Streisand
Barbara Streisand원래의
2024-10-30 05:43:021045검색

 How can you reliably initialize static members in templated C   classes using nested helper structs?

템플릿 클래스 및 초기화 도우미의 정적 멤버 초기화

C에서는 중첩된 도우미 구조체를 사용하여 정적 멤버를 초기화할 수 있습니다. 이 접근 방식은 템플릿이 아닌 클래스에는 잘 작동하지만 템플릿 매개변수가 있는 클래스에서는 문제가 발생할 수 있습니다.

문제 설명

정적 멤버 초기화 도우미가 템플릿 클래스:

<code class="cpp">struct A
{
    struct InitHelper
    {
        InitHelper() { A::mA = "Hello, I'm A."; }
    };
    static std::string mA;
    static InitHelper mInit;

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

template<class T>
struct B
{
    struct InitHelper
    {
        InitHelper() { B<T>::mB = "Hello, I'm B."; } // [3]
    };
    static std::string mB;
    static InitHelper mInit; // [4]

    static const std::string& getB() { return mB; }
    static InitHelper& getHelper() { return mInit; }
};</code>

이 시나리오에서는 다음과 같이 관찰됩니다.

  • [1]과 [2]를 주석 처리하면 예상대로 출력됩니다. "A = Hello, I'm A.".
  • [1]을 주석 처리하지 않으면 예상되는 "Hello, I'm B" 대신 "A = Hello, I'm A.nB = "가 출력됩니다. ".
  • [1]과 [2]를 모두 주석 처리하지 않으면 예상대로 출력됩니다. "A = 안녕하세요, 저는 A.nB = 안녕하세요, 저는 B입니다.".
  • [1]이 주석 처리되고 [2]가 주석 처리되지 않은 경우 프로그램은 [3]에서 세그폴트가 발생합니다.

설명

예기치 않은 동작은 정적 멤버 초기화 동작에서 비롯됩니다. 템플릿 클래스. ISO/IEC C 2003 표준(14.7.1)에 따르면 정적 데이터 멤버의 초기화는 정적 데이터 멤버 자체가 해당 정의가 존재해야 하는 방식으로 사용되는 경우에만 발생합니다.

  • A의 경우 정적 데이터 멤버 mA는 main에서 명시적으로 참조되므로 main 함수가 실행되기 전에 초기화가 발생합니다.
  • B의 경우 B::getB()에 액세스합니다. B::mB를 참조하여 초기화를 트리거합니다. 그러나 B::getHelper()에 액세스하면 B::mInit가 직접 사용되지 않고 초기화 도우미에 별칭만 반환됩니다.

해결 방법

To 암시적 초기화에 대한 의존을 피하고 일관된 초기화 순서를 보장하려면 클래스 템플릿에서 정적 데이터 멤버를 명시적으로 특수화하는 것이 좋습니다. 이 경우:

<code class="cpp">template<>
std::string B<int>::mB = "Hello, I'm B (int specialization).";</code>

템플릿 클래스의 각 인스턴스화에 대해 정적 데이터 멤버를 명시적으로 특수화함으로써 초기화가 명시적으로 트리거되고 초기화 도우미에 액세스하지 않고도 원하는 동작이 달성됩니다.

위 내용은 중첩된 도우미 구조체를 사용하여 템플릿 기반 C 클래스의 정적 멤버를 어떻게 안정적으로 초기화할 수 있나요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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