可变模板元编程:clang++或g++中的一个bug



考虑将数组从一种类型强制转换为另一种类型的可变类型模板:

#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;
}

这段代码在g++4.7和g++4.8下可以很好地编译,但在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);

是g++过于宽松还是clang++的一个bug(如果是,clang++是否有一个公开的bug跟踪器)?

是的,这就是clang中已经报告并修复的错误。

最新更新