http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53248
Bug #: 53248 Summary: std::array<T,0> doesn't work when T is not default-constructible Classification: Unclassified Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: dwalke...@yahoo.com (I'm using GCC 4.7.0 from MacPorts on my Mac OS X 10.4.11/Tiger (32-bit PowerPC).) Here's a reduced example of my code: //================================== #include <array> #include <typeindex> #include <typeinfo> template < typename ...Types > union super_union; template < > union super_union<> { static auto optioned_types() -> std::array<std::type_index, 0> { return std::array<std::type_index, 0>{ {} }; } }; template < typename Head, typename ...Tail > union super_union<Head, Tail...> { static auto optioned_types() -> std::array<std::type_index, 1 + sizeof...(Tail)> { using std::type_index; return { {type_index(typeid(Head)), type_index(typeid(Tail))...} }; } Head data; super_union<Tail...> rest; }; int main() { return 0; } //================================== When I compile it, I get: //================================== [daryle]$ g++-mp-4.7 -std=c++11 test_array.cpp test_array.cpp: In static member function 'static std::array<std::type_index, 0ul> super_union<>::optioned_types()': test_array.cpp:12:49: error: could not convert '<brace-enclosed initializer list>()' from '<brace-enclosed initializer list>' to 'std::array<std::type_index, 0ul>::value_type {aka std::type_index}' //================================== When I change the returned initialized value on line 12 to "std::array<std::type_index, 0>{}", I get the same result. But when I change it to "std::array<std::type_index, 0>()", I get: //================================== [daryle]$ g++-mp-4.7 -std=c++11 test_array.cpp test_array.cpp: In static member function 'static std::array<std::type_index, 0ul> super_union<>::optioned_types()': test_array.cpp:12:45: error: use of deleted function 'std::array<std::type_index, 0ul>::array()' In file included from test_array.cpp:1:0: /opt/local/include/gcc47/c++/array:61:12: note: 'std::array<std::type_index, 0ul>::array()' is implicitly deleted because the default definition would be ill-formed: /opt/local/include/gcc47/c++/array:61:12: error: no matching function for call to 'std::type_index::type_index()' /opt/local/include/gcc47/c++/array:61:12: note: candidates are: In file included from test_array.cpp:2:0: /opt/local/include/gcc47/c++/typeindex:51:5: note: std::type_index::type_index(const std::type_info&) /opt/local/include/gcc47/c++/typeindex:51:5: note: candidate expects 1 argument, 0 provided /opt/local/include/gcc47/c++/typeindex:49:10: note: constexpr std::type_index::type_index(const std::type_index&) /opt/local/include/gcc47/c++/typeindex:49:10: note: candidate expects 1 argument, 0 provided /opt/local/include/gcc47/c++/typeindex:49:10: note: constexpr std::type_index::type_index(std::type_index&&) /opt/local/include/gcc47/c++/typeindex:49:10: note: candidate expects 1 argument, 0 provided //================================== Looking at <array> on the web at your documentation pages, there is no specialization of "std::array<T,N>" for "std::array<T,0>"; you just nudge the element count to 1 when it would have been zero. That secret element still needs to be specified, since std::type_index doesn't have a default constructor, although no initializers are logically necessary for an empty array (i.e. the work-around abstraction leaks). The first way I see around it is to make an explicit specialization that's data-less.