5

일부 템플릿 metaprogramming에 대한 컴파일 타임에 정적 테이블/배열을 생성 한 시간에 일부 코드를 한 번 썼습니다. 아이디어는 C 스타일 문자열을 컴파일 할 때 컴파일 할 수 있다는 것입니다 (이들은 단지 char 배열 임)). 아이디어와 코드를 기반으로한다 David Linanswer :정적 테이블 생성은 GCC에서 작동하지만 clang에서는 작동하지 않습니다. 깡패가 도청 당했어?

#include <iostream> 

const int ARRAY_SIZE = 5; 

template <int N, int I=N-1> 
class Table : public Table<N, I-1> 
{ 
public: 
    static const int dummy; 
}; 

template <int N> 
class Table<N, 0> 
{ 
public: 
    static const int dummy; 
    static int array[N]; 
}; 

template <int N, int I> 
const int Table<N, I>::dummy = Table<N, 0>::array[I] = I*I + 0*Table<N, I-1>::dummy; 

template <int N> 
int Table<N, 0>::array[N]; 

template class Table<ARRAY_SIZE>; 

int main(int, char**) 
{ 
    const int *compilerFilledArray = Table<ARRAY_SIZE>::array; 
    for (int i=0; i < ARRAY_SIZE; ++i) 
     std::cout<<compilerFilledArray[i]<<std::endl; 
} 

GCC 4.9.2 작품이 코드 컴파일 :

$ g++-4.9 -Wall -pedantic b.cpp 
$ ./a.out 
0 
1 
4 
9 
16 

연타 3.5 불평하지만 :

$ clang++ -Wall -pedantic b.cpp 
Undefined symbols for architecture x86_64: 
    "Table<5, 0>::dummy", referenced from: 
     ___cxx_global_var_init in b-b8a447.o 
ld: symbol(s) not found for architecture x86_64 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 

dummyarray은 모두 Table 클래스 외부에 정의되어 있습니다 (선언 된 곳). 내가 알 수있는 한 이것은 링커 요구 사항을 충족시켜야합니다.

clang의 버그입니까?

답변

6

모든 기본 및 부분 전문화 정적 데이터 멤버를 별도로 정의해야합니다.

유일하게 정의 된 정적 데이터 멤버 인 Table<N, I>::dummy입니다. [temp.class.spec.mfunc]/1 1 :

클래스 정의가 정의되어야한다 필요 방법에 사용되는 템플릿 부분 특수화 부재; 기본 템플릿의 멤버 정의가 클래스 템플릿 부분 전문화 멤버의 정의로 사용되지 않습니다.

이것은 또한 GCC가 잘못되었음을 의미합니다. 그게 문제 야. 잘 컴파일해야

template <int N> 
const int Table<N, 0>::dummy = 0; 

를 추가
Eitherway을. 특히


1) 위에서 인용 동일한 섹션 :

클래스 템플릿의 구성원의 템플릿 파라미터리스트 부분 전문화의 템플릿 파라미터리스트와 일치한다 클래스 템플릿 부분 전문화.
클래스 템플릿 부분 전문화의 구성원 인 템플릿 인수 목록은 클래스 템플릿 부분 전문화의 템플릿 인수 목록과 일치해야합니다. 인수리스트가 같은이어야 부분 특수화 와 부재를 형성에 사용되는 것을 의미

. 그렇지 않으면 그 구성원은 결코 정의되지 않습니다.

+0

아, 맞아! 나는 한 번만 투표 할 수있는 수치 스럽다. 또한 표준 견적을받을 때이를 기다리고 있습니다. – Cornstalks

+0

@Cornstalks 그들은 거기에 있습니다 :) – Columbo

+0

gcc 버그 신고에 대한 링크를 추가 할 수 있습니까? –