Consider this unconditional madness of a template to pass an array from one type to another:
#include <array> #include <type_traits> template <typename Type> class Converter { public: template <typename OtherType, unsigned int OtherSize, class Array, typename... Types, class = typename std::enable_if<sizeof...(Types) != OtherSize>::type> static constexpr const std::array<OtherType, OtherSize> convert(const Array source, const Types&... values); template <typename OtherType, unsigned int OtherSize, class Array, typename... Types, class = typename std::enable_if<sizeof...(Types) == OtherSize>::type> static constexpr const std::array<OtherType, OtherSize> convert(const Array, const Types... values); }; template <typename Type> template <typename OtherType, unsigned int OtherSize, class Array, typename... Types, class> constexpr const std::array<OtherType, OtherSize> Converter<Type>::convert(const Array source, const Types&... values) { return convert<OtherType, OtherSize>(source, values..., OtherType(source[sizeof...(values)])); } template <typename Type> template <typename OtherType, unsigned int OtherSize, class Array, typename... Types, class> constexpr const std::array<OtherType, OtherSize> Converter<Type>::convert(const Array, const Types... values) { return std::array<OtherType, OtherSize>({{values...}}); } int main(int argc, char* argv[]) { Converter<double>::convert<int, 3>(std::array<double, 3>({{1., 2., 3.}})); return 0; }
This code compiles well under g ++ 4.7 and g ++ 4.8, but not under clang ++ 3.2:
main.cpp:16:67: error: conflicting types for 'convert' constexpr const std::array<OtherType, OtherSize> Converter<Type>::convert(const Array source, const Types&... values) ^ main.cpp:9:65: note: previous declaration is here static constexpr const std::array<OtherType, OtherSize> convert(const Array source, const Types&... values); ^ main.cpp:23:67: error: conflicting types for 'convert' constexpr const std::array<OtherType, OtherSize> Converter<Type>::convert(const Array, const Types... values) ^ main.cpp:11:65: note: previous declaration is here static constexpr const std::array<OtherType, OtherSize> convert(const Array, const Types... values);
Is g ++ too valid or is it a bug in clang ++ (and if so, is there a public bugtracker clang ++)?