5

Napisałem kiedyś jakiś kod, który wygenerował statyczną tablicę/tablicę w czasie kompilacji dla metaprogramowania niektórych szablonów (chodzi o to, że łańcuchy w stylu C mogą być budowane w czasie kompilacji (są to tylko tablice char)). Pomysł i kod opiera się David Lin „s answer:Generowanie tabel statycznych działa z GCC, ale nie klang; czy błąd jest 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; 
} 

Kompilacja tego kodu z GCC 4.9.2 działa:

Clang 3.5 narzeka, ale:

$ 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) 

dummy i array mają podane definicje poza klasą Table (gdzie są zadeklarowane). O ile mogę powiedzieć, to powinno spełniać wymagania linkera.

Czy to błąd z dzwonkiem?

Odpowiedz

6

Każda główna i częściowa specjalizacja statycznych elementów danych musi być zdefiniowana osobno.

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

Jedyne zdefiniowany tutaj jest Table<N, I>::dummy - specjalności główny element dane statyczne. [Temp.class.spec.mfunc]/1 :

członków klasy szablon częściowe specjalizacji, które są wykorzystywane w taki sposób, że wymaga określenia są zdefiniowane; Definicje członków szablonu podstawowego nigdy nie są używane jako definicje dla członków częściowej specjalizacji szablonów klasy.

To również oznacza, że ​​GCC jest tutaj błędne. To błąd.
Eitherway, dodając

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

powinien skompilować grzywny.


1) W szczególności, w tej samej sekcji jako cytat powyżej:

Lista parametrów szablonu członka szablonu klasy częściowe specjalizacja powinna odpowiadać listę parametrów szablonu szablon częściowej specjalizacji szablonu.
Lista szablonów argumentów dla częściowej specjalizacji szablonów klas musi być zgodna z szablonową listą szablonów części szablonów klasy .

Oznacza to, że listy argumentów wykorzystywane do definiowania częściową specjalizację i jej państw musi być taka sama. W przeciwnym razie ten członek nigdy nie zostanie zdefiniowany.

+0

Ach, to ma sens! Szkoda, że ​​mogę głosować tylko raz. Poza tym czekam na standardowe cytaty, kiedy je otrzymasz. – Cornstalks

+0

@Cornstalks Oni tam są :) – Columbo

+0

Czy możesz dodać link do raportu o błędzie gcc, proszę? –

Powiązane problemy