Neargye / magic_enum

Static reflection for enums (to string, from string, iteration) for modern C++, work with any enum type without any macro or boilerplate code
MIT License
4.8k stars 429 forks source link

g++ 11.2: Compile error (`magic_enum::detail::count_v<Color>' has incomplete type`) #184

Closed pthom closed 2 years ago

pthom commented 2 years ago

Hello,

I encountered a compilation error with g++11.2.0.

 error: the type 'const auto' of 'constexpr' variable 'magic_enum::detail::count_v<Color>' is not literal
 'const auto magic_enum::detail::count_v<Color>' has incomplete type

With the following code:


enum class Color { RED = 2, BLUE = 4, GREEN = 8 };
void Foo2()
{
    // The commented line below will act as a workaround, and let the code compile!
    // std::size_t color_count = magic_enum::enum_count<Color>(); (void)color_count;

    magic_enum::enum_for_each<Color>([] (auto val) {
        Color type = val;
        const char* name = magic_enum::enum_name(type).data();
        std::cout << name;
    });

}

As a workaround, if I uncomment the line std::size_t color_count = magic_enum::enum_count<Color>(); (void)color_count;, then the compiler is happy. Strange!

Here is the complete log:

In file included from main.cpp:4:
magic_enum.hpp: In instantiation of 'constexpr const auto magic_enum::detail::count_v<Color>':
magic_enum.hpp:902:98:   required by substitution of 'template<class E, class Lambda, class D> using for_each_t = decltype (for_each<D>(declval<Lambda>(), std::make_index_sequence<count_v<D> >{})) [with E = Color; Lambda = Lambda; D = Color]'
magic_enum.hpp:1278:20:   required by substitution of 'template<class E, class Lambda> constexpr magic_enum::detail::enable_if_t<E, magic_enum::detail::for_each_t<E, Lambda> > magic_enum::enum_for_each(Lambda&&) [with E = Color; Lambda = <missing>]'
main.cpp:261:37:   required from here
magic_enum.hpp:580:31: error: the type 'const auto' of 'constexpr' variable 'magic_enum::detail::count_v<Color>' is not literal
  580 |         inline constexpr auto count_v = values_v<E>.size();
      |                               ^~~~~~~
magic_enum.hpp:580:31: error: 'const auto magic_enum::detail::count_v<Color>' has incomplete type
main.cpp: In function 'void Foo2()':
main.cpp:261:37: error: no matching function for call to 'enum_for_each<Color>(Foo2()::<lambda(auto:25)>)'
  261 |     magic_enum::enum_for_each<Color>([] (auto val) {
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~
  262 |         Color type = val;
      |         ~~~~~~~~~~~~~~~~~            
  263 |         const char* name = magic_enum::enum_name(type).data();
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  264 |         std::cout << name;
      |         ~~~~~~~~~~~~~~~~~~           
  265 |     });
      |     ~~                               
In file included from main.cpp:4:
magic_enum.hpp:1278:20: note: candidate: 'template<class E, class Lambda> constexpr magic_enum::detail::enable_if_t<E, magic_enum::detail::for_each_t<E, Lambda> > magic_enum::enum_for_each(Lambda&&)'
 1278 |     constexpr auto enum_for_each(Lambda&& lambda) -> detail::enable_if_t<E, detail::for_each_t<E, Lambda>> {
      |                    ^~~~~~~~~~~~~
magic_enum.hpp:1278:20: note:   substitution of deduced template arguments resulted in errors seen above
Neargye commented 2 years ago

Check fix in master please.

pthom commented 2 years ago

Wow, this is first class service! Thanks a lot, the fix works perfectly.

Warm thoughts from Paris. My heart stands with Ukraine and Kyiv.