This seems to be a compiler bug to me.
I tried you example on gcc 4.1.2 (codepad), and you have to explicitely note the variable as having external linkage (const imply internal linkage unless specified otherwise, the following code is C++03):
struct s { int i; };
template<const s* _arr>
class struct_array
{
public:
static const s arr;
template<int >
struct inner
{
};
};
template<const s* _arr>
const s struct_array<_arr>::arr = _arr[0];
// Notice the 'extern'
extern const s s_objs[] = {{ 42 }};
int main()
{
struct_array<s_objs> t_obj;
return 0;
}
I also have it working on gcc 4.8.1 without C++11 enabled.
So, the workaround is:
change
constexpr const s s_objs[] = ...;
to
extern const s s_objs[] = ...;
If you want the variable to be a static class member, then you have to specify it to have external linkage:
struct data
{
static const s s_objs[1];
};
extern const s data::s_objs[1] = {{ 42 }};
This gives me a warning on gcc 4.7, not on 4.8. Also it doesn't compile on Rise4Fun. So, I'm not sure whether this is pure standard or a bug in one of the compiler.