정적 데이터 구성원을 헤더 전용 라이브러리에 포함시키는 방법은 무엇입니까?

StackOverflow https://stackoverflow.com//questions/11709859

  •  13-12-2019
  •  | 
  •  

문제

비 템플릿 라이브러리 클래스에 정적 멤버를 갖는 가장 좋은 방법은 무엇입니까? 클래스 사용자의 멤버 정의의 부담을 배치하지 않고?

이 수업을 제공하고 싶습니다 :

class i_want_a_static_member
{
    static expensive_resource static_resource_;

public:
    void foo()
    {
        static_resource_.bar();
    }
};
.

다음 클래스의 사용자는 어딘가에 정적 멤버를 정의하는 것을 잊지 않아야합니다. (이미 이미 답변 됨 많은 시간 ) :

// this must be done somewhere in a translation unit
expensive_resource i_want_a_static_member::static_resource_;
.

아래의 답변이 있지만 몇 가지 단점이 있습니다.더 나은 우아한 솔루션이 있고 더 우아한 솔루션이 있습니까?

도움이 되었습니까?

해결책

C ++ 17 이상

비 동적 초기화를 위해 inline static 변수를 사용합니다.

struct Foo
{
    inline static int I = 0;
};
.

및 사용 함수 로컬 정적 변수는 그렇지 않으면 다음과 같습니다.

struct Foo
{
    static std::string& Bar()
    {
        static std::string S = compute();
        return S;
    }
};
.

C ++ 14 및 아래

함수 로컬 statics를 사용하면 사용할 수 없으므로

어떤 이유로 정적 데이터 멤버 에 대해 실제로 원하는 경우 템플릿 트릭을 사용할 수 있습니다 :

template <typename T = void>
struct Foo
{
     static int I = 0; // inline initialization only for simple types.
};

template <typename T>
int Foo<T>::I;
.

로컬 통계

동적 초기화가 필요한 자원에 대해서는 로컬 정적을 사용하는 것이 가장 좋습니다.

파일 범위 또는 클래스 범위 statics가 동적으로 초기화되는 순서는 일반적으로 다른 사람의 초기화의 일부로 초기화되지 않은 정전기를 읽으려고 할 때 정적 초기화 순서로 이어집니다. 로컬 정적 첫 번째 사용시 초기화 된 Lazily로 문제를 해결하십시오.

로컬 통계를 사용하는 데 약간의 오버 헤드가 있습니다. C ++ 11에서 초기화는 스레드 안전성이어야합니다. 일반적으로 원자 읽기 및 잘 예측 된 지점에 의해 모든 액세스가 게이트 된 경우

다른 팁

내 솔루션은 정적 멤버가 템플릿에서 잘 작동 하므로이 홀더를 기본 클래스로 사용하는 것처럼 템플릿 홀더 클래스를 사용하는 것입니다.

template <typename T>
struct static_holder
{
    static T static_resource_;
};

template <typename T>
T static_holder<T>::static_resource_;
.

이제 홀더 클래스를 사용합니다.

class expensive_resource { /*...*/ };

class i_want_a_static_member : private static_holder<expensive_resource>
{
public:
    void foo()
    {
        static_resource_.bar();
    }
};
.

그러나 홀더 클래스에 구성원의 이름이 지정되면 둘 이상의 정적 멤버에 대해 동일한 홀더를 사용할 수 없습니다.

C ++ 17. 이제 인라인 변수를 사용하여 다음을 수행 할 수 있습니다.

static const inline float foo = 1.25f;
.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top