우리는 싱글 톤을 구현하기 위해 curiously recurring template pattern을 사용하고 있습니다. 그러나 최근의 Clang 버전에서는 Woundefined-var-template 경고가 나타납니다. "명시 적 인스턴스화 선언"을 추가하는 것이 좋습니다.Clang을 사용하여 CRTP Singleton을 컴파일 할 때 "명시 적 인스턴스화 선언"이 부족하다는 문제를 해결하는 방법은 무엇입니까?
이 작업을 시도했지만, 싱글 톤 템플릿 클래스 멤버 변수의 정의가있는 컴파일 단위에서 "인스턴스화 후 명시 적 전문화"에 대한 오류가 발생합니다.
이 경고로 강조 표시된 문제를 해결하는 적절한 구성 요소는 무엇입니까?
간체 정보 (논리의 대부분은 MCVE를 만들기 위해, 제거 된) :
SingletonBase.hh :
template < class T > class SingletonBase {
public:
static T * get_instance() {
if (! instance_) {
instance_ = T::create_singleton_instance();
}
return instance_;
}
private:
static T * instance_;
};
Singleton.hh :
#include "SingletonBase.hh"
class Singleton : public SingletonBase<Singleton> {
friend class SingletonBase<Singleton>;
public:
int do_stuff(int v) { return v+2; }
private:
static Singleton * create_singleton_instance() {
return new Singleton;
}
};
싱글 톤 .cc :
#include "Singleton.hh"
template <> Singleton * SingletonBase<Singleton>::instance_(nullptr);
최근 버전의 clang (3.9.0; but not clang 3.7), Singleton.cc 이외의 파일을 컴파일 할 때 경고 메시지가 나타납니다. 그것이 내가 명시 적 인스턴스화 선언 구문이되어야합니다 lead to believe이야 무엇으로 (-std = C++ 11 -Werror와)
In file included from OtherFile.cc:2:
In file included from ./Singleton.hh:2:
./SingletonBase.hh:5:16: warning: instantiation of variable 'SingletonBase<Singleton>::instance_' required here, but no definition is available [-Wundefined-var-template]
if (! instance_) {
^
OtherFile.cc:5:25: note: in instantiation of member function 'SingletonBase<Singleton>::get_instance' requested here
return Singleton::get_instance()->do_stuff(4);
^
./SingletonBase.hh:11:18: note: forward declaration of template entity is here
static T * instance_;
^
./SingletonBase.hh:5:16: note: add an explicit instantiation declaration to suppress this warning if 'SingletonBase<Singleton>::instance_' is explicitly instantiated in another translation unit
if (! instance_) {
^
1 error generated.
나는, Singleton.hh의 마지막에 다음 줄을 추가했다. 그 OtherFile.cc를 컴파일하여 문제를 해결하는 동안 Singleton.cc
를 컴파일 할 때
extern template Singleton* SingletonBase< class Singleton >::instance_;
, 그것은 새로운 오류가 발생
Singleton.cc:3:57: error: explicit specialization of 'instance_' after instantiation
template <> Singleton * SingletonBase<Singleton>::instance_(nullptr);
^
./Singleton.hh:14:66: note: explicit instantiation first required here
extern template Singleton* SingletonBase< class Singleton >::instance_;
^
1 error generated.
나는 이러한 경고/오류를 해결하기 위해 여기에 일을해야 무엇
? 내가 이해하지 못하는 명시 적 인스턴스화 선언에 대한 더 적절한 구문이 있습니까?
template<class T>
struct SingletonBase {
static T& get_instance() {
static T instance;
return instance;
}
};
이의 스레드로부터 안전하고 경고를 제거합니다
왜 오 왜? 고정 멤버 var를 만들고 잠금이 아니므로 스레드로부터 안전하지 않습니다. 당신은'get_instance()'에 그 static을 넣을 수 있습니다. if를 thread-safe로 남겨 둡니다. 기본 클래스는 이것이 싱글 톤인 것을 보장하지는 않지만 create_instance 함수가 필요합니다. 어느 시점에서든 인터페이스를 건드리지 않고 두 개의 'Singleton'인스턴스를 만들 수 있습니다. 그것을 파괴 할 수는 없습니다. 같은 시간에 기본 및 자손 (singleton)을 가질 수 있습니다. 당신은 유출하고 절대 소멸자를 부르지 않습니다. 고쳐? 이러한 소스를 삭제하고 다시 시작하십시오. (불쾌감을주지 않으면 적절한 지침을 제공 할 수 있습니다.) – lorro
@ Iorro MCVE를 제공하기 위해 대부분의 세부 사항 (스레드 안전 비트 포함)을 찢어 냈습니다. "베스트 프랙티스"를 고려한 싱글 톤 구현을 가지고 있다면, 그것을 코멘트에 링크 할 수는 있지만 원래의 질문은 여전히 유효합니다. –
이것은 매우 중요합니다. 주 질문 섹션에 주석을 추가하는 것이 좋습니다. 그렇지 않으면 사람들이 컴파일러 오류가 아니라이를 수정하려고합니다. 멤버 변수 -> 함수 static 변수 수정이 작동합니까? 아니면 멤버로 유지해야 할 이유가 있습니까? – lorro