4

The following code compiles with clang and msvc but not with gcc. It seems gcc does not match the specialisation because of the conversion from signed to unsigned and therefore selects the primary template.

Which compiler is correct? Or is this even UB?

#include <utility>

template<class X>
struct Foo;

template<std::size_t unsigned_integer>
using uint_ = std::integral_constant<std::size_t, unsigned_integer>;

template<int signed_integer>      // Doesn't work with gcc.  
struct Foo<uint_<signed_integer>> // <- conversion happens here
{
};

// template<int signed_integer>
// struct Foo<uint_<std::size_t(signed_integer)>> // Doesn't work either
// {
// };

// template<std::size_t unsigned_integer>
// struct Foo<uint_<unsigned_integer>> // Works
// {};

int main() {
    Foo<uint_<2>> f;

    return 0;
}

Live example here.

florestan
  • 4,405
  • 2
  • 14
  • 28
  • Looks like a disagreement in how the compilers handle implicit built-in conversions when searching for partial specializations. See my simplification of your example here: https://godbolt.org/z/vQzvp_ . Both GCC and clang reject `Derived*` to `Base*` conversions, but only GCC rejects integer promotion. – Filipp Mar 16 '20 at 12:53
  • Also: https://stackoverflow.com/q/46555186/5376789 – xskxzr Mar 16 '20 at 13:40
  • @xskxzr Yeah, I think this answers the question. Thank you! – florestan Mar 17 '20 at 11:04

0 Answers0