Search code examples
c++templatesc++17autonon-type

g++7.2.0 fails auto non-type parameter deduction


I'm trying to use auto non-type parameter(c++17). I expected that the 'Sample1::type' should be 'integral_constraint<int, 0>', but it was the same as 'Sample0::type'.

Is it g++ bug or my misunderstandings about the feature? I use g++ (Ubuntu 7.2.0-8ubuntu3) 7.2.0 on Ubuntu 17.10.

-- auto_param.cxx --
#include <iostream>
#include <type_traits>
#include <boost/type_index.hpp>

template <auto V>
struct Value {
  using type = std::integral_constant<decltype(V), V>;
};

template <typename T>
auto demangle() {
  return boost::typeindex::type_id_with_cvr<T>().pretty_name();
}

void zero_as_uint() {
  using Sample0 = Value<0u>;
  std::cout << __func__ << ": " << demangle<Sample0::type>() << std::endl;
}

void zero_as_int() {
  using Sample1 = Value<0>;
  std::cout << __func__ << ": " << demangle<Sample1::type>() << std::endl;
}

int main(int, char**) {
  zero_as_uint();
  zero_as_int();
  return 0;
}
-----------------------------
$ g++ -Wall -std=c++17 auto_param.cxx && ./a.out
zero_as_uint: std::integral_constant<unsigned int, 0u>
zero_as_int: std::integral_constant<unsigned int, 0u>

I found clang++ deduced as I expected.

$ clang++-5.0 -Wall -std=c++17 auto_param.cxx && ./a.out
zero_as_uint: std::integral_constant<unsigned int, 0u>
zero_as_int: std::integral_constant<int, 0>

Solution

  • That's a bug in gcc. A further reduced example looks like this:

    #include <type_traits>
    
    template <auto V>
    struct Value {
      using type = std::integral_constant<decltype(V), V>;
    };
    
    static_assert(!std::is_same_v<Value<0u>::type, Value<0>::type>);
    

    Those two types can't possibly be the same, as they refer to different template instantiations. It looks like gcc has always had the bug, but it is fixed in the latest trunk.