I가 다음과 같은 C++ 11 코드 (간체 버전) :정적 constexpr 클래스 멤버가 클래스 외부 정의가 필요한 경우는 언제입니까?
struct Info
{
const char * name;
int version;
};
class Base
{
public:
const Info info;
Base (Info info) : info (info) {}
};
class Derived : public Base
{
public:
static constexpr Info info = {"Foobar", 2};
Derived() : Base (info) {}
};
int main()
{
static Derived derived;
return 0;
}
GCC 4.9.1 컴파일 및 링크이 코드 벌금을. 반면에 Clang 3.5.0은 정의되지 않은 참조에 대해 불평합니다 :
/tmp/test-109c5c.o: In function `main':
test.cc:(.text+0x1c): undefined reference to `Derived::info'
test.cc:(.text+0x22): undefined reference to `Derived::info'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
맞습니까? 이 코드가 합법적인가 아닌가? static constexpr 멤버 (대부분 this question)에 관한 규칙에 대한 나의 이해는 변수의 주소가 사용될 때만 클래스 밖의 정의가 필요하다는 것입니다. 하지만 Derived :: info의 주소를 사용하지 않거나 어디에서나 참조를 사용합니다. Base 생성자에만 값을 전달합니다. 내가 찾은
다양한 해결 방법 :
- 모두 생성자 (자료 및 파생) constexpr를 확인합니다. 이것은 예제의 것보다 더 복잡한 실제 클래스의 옵션 일 수도 있고 아닐 수도 있습니다. 어쨌든 그것을 시도 할 것입니다.
- main에서 파생 된 인스턴스를 정적 기간이 아닌 자동 기간으로 선언하십시오. 이는 실제 프로젝트에 대한 옵션이 아닙니다. Derived 클래스는 플러그인 구현이며, 인스턴스를 공유 객체의 공용 심볼로 내 보내야합니다.
- Derived :: info를 완전히 제거하고 중괄호로 초기화 된 임시 객체 (예 :
Base ({"Foobar", 2})
)로 Base 생성자를 호출합니다. 이 솔루션을 사용할 수는 있지만 더 많은 멤버가 struct Info에 추가되므로 추한 것입니다 (제 의견으로는).
[vector :: push_back odr - 정적 클래스 멤버에 대한 정의되지 않은 참조를 일으키는 값을 사용할 수 있습니다.] (http://stackoverflow.com/questions/272900/undefined-reference-to-static-class-member) –
데이터 멤버 대신 멤버 함수로 만들면 어떻습니까? – imreal
@ πάνταῥεῖ 나는 std :: vector를 사용하지 않고있다. 그러나 당신의 링크는 나를 올바른 길로 인도한다. 감사! –