5

Tôi đã viết một số mã một lần trên một thời gian tạo ra một bảng/mảng tĩnh tại thời gian biên dịch cho một số mẫu lập trình meta (ý tưởng là các chuỗi kiểu C có thể được xây dựng tại thời gian biên dịch (chúng chỉ là char mảng)). Ý tưởng và mã dựa tắt David Lin 's answer:Tạo bảng tĩnh hoạt động với GCC nhưng không hoạt động; là kêu vang?

#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; 
} 

Biên dịch mã này với GCC 4.9.2 công trình:

Clang 3.5 phàn nàn, mặc dù:

$ 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 đều được đưa ra định nghĩa bên ngoài lớp Table (nơi chúng được khai báo). Theo như tôi có thể nói, điều này sẽ đáp ứng các yêu cầu của trình liên kết.

Đây có phải là lỗi với tiếng kêu không?

Trả lời

6

Mỗi chuyên môn chính và một phần các thành phần dữ liệu tĩnh phải được xác định riêng.

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

Điều duy nhất được xác định ở đây là Table<N, I>::dummy - thành viên dữ liệu tĩnh chuyên ngành chính. [Temp.class.spec.mfunc]/1 :

Lớp mẫu thành viên chuyên môn hóa một phần được sử dụng trong một cách mà đòi hỏi một định nghĩa được quy định; các định nghĩa của thành viên của mẫu chính không bao giờ được sử dụng làm định nghĩa cho thành viên của chuyên môn từng phần của mẫu lớp.

Điều này cũng ngụ ý rằng GCC sai ở đây. Đó là một lỗi.
Eitherway, thêm

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

Nên biên dịch tiền phạt.


1) Đặc biệt, trong phần giống như trích dẫn ở trên:

Danh sách mẫu tham số của một thành viên của một lớp mẫu phần chuyên môn có trách nhiệm phù hợp với danh sách mẫu tham số của lớp học mẫu chuyên môn hóa một phần.
Danh sách đối số mẫu của thành viên của chuyên môn từng phần của mẫu lớp phải khớp với danh sách đối số mẫu mẫu chuyên biệt từng phần của mẫu lớp.

Điều đó có nghĩa rằng danh sách đối số dùng để xác định chuyên môn hóa một phần và là thành viên của nó phải giống. Nếu không thành viên đó không bao giờ được xác định.

+0

Ah, điều đó có ý nghĩa! Đó là một sự xấu hổ tôi chỉ có thể bỏ phiếu một lần. Ngoài ra, tôi đang mong chờ các báo giá tiêu chuẩn khi bạn nhận được chúng. – Cornstalks

+0

@Cornstalks Họ đang ở đó :) – Columbo

+0

Bạn có thể thêm liên kết đến báo cáo lỗi gcc không? –

Các vấn đề liên quan