Potrzebowałem manupulować ciągiem znaków w czasie kompilacji więc napisałem sobie oto taki wrapper:
template <char ...Cs>
struct char_seq {
static constexpr const char
value[sizeof...(Cs) + 1] =
{Cs..., '\0'};
};
#include <iostream>
int main() {
std::cout
<< char_seq<'0', '1'>::value
<< std::endl;
return 0;
}
Ku mojemu zaskoczeniu powyższy kod nie kompiluje się w standardzie c++11/14, linker wyrzuca taki oto błąd:
// GCC 9.1
/usr/bin/ld: /tmp/ccZZZsJC.o: in function `main':
1.cpp:(.text+0x7): undefined reference to `char_seq<(char)48, (char)49>::value'
collect2: error: ld returned 1 exit status
// Clang 8.0.1
/usr/bin/ld: /tmp/1-bfa92b.o: in function `main':
1.cpp:(.text+0x12): undefined reference to `char_seq<(char)48, (char)49>::value'
clang-8: error: linker command failed with exit code 1 (use -v to see invocation)
Co ciekawe zarówno kompilując za pomocą clanga jak i w gcc z standardem c++17 wszystko ładnie działa. Prawdopodobnie jest jakiś zapisek w standardzie c++11/14 który uniemożliwia zlinkowanie się tego kodu (albo jest to bug kompilatorów lub linkera, ale w to nie wierze bo działą poprawnie w nowszym standardzie).
Czy ktoś z was może wie dlaczego powyższy kod nie kompiluje się w standardzie c++11/14?