c++c++20variadic-templatesfold-expression

How to expand a NTTP parameter pack with a fold expression


I have a function (bar) that takes a pack of NTTP, hax can I expand the pack using fold expression so that each element of the pack is the template parameter of another function (foo).

#include <iostream>
#include <string_view>
#include <type_traits>

struct TestStruct
{};

template <typename Type>
struct TypedTestDesc {
  using TestTypeT = Type;
  const char* m_typeName;
};

template <auto TypedTestDesc>
void foo()
{
  if constexpr (std::is_default_constructible_v<typename TypedTestDesc::Type>) {
    std::cout << TypedTestDesc.m_typeName << "\n";
    typename TypedTestDesc::Type tmp {};
  }
}

template <auto ...TypedTestDescList>
void bar()
{
  (foo<TypedTestDesc>(), ...);
}

int main()
{
  foo<TypedTestDesc<TestStruct>{"TestStruct"}>();
}

In Msvc, I get this error:

(27): error C7515: a fold expression must contain an unexpanded parameter pack

Solution

  • This works:

    #include <iostream>
    #include <type_traits>
    
    struct TestStruct
    {};
    
    template <typename Type>
    struct TypedTestDesc {
      using TestTypeT = Type;
      const char* m_typeName;
    };
    
    template <auto desc>
    void foo()
    {
      using DescType = typename decltype(desc)::TestTypeT;
      if constexpr (std::is_default_constructible_v<DescType>) {
        std::cout << desc.m_typeName << "\n";
        DescType tmp {};
      }
    }
    
    template <auto ...TypedTestDescList>
    void bar()
    {
      (foo<TypedTestDescList>(), ...);
    }
    
    int main()
    {
      static const char name[] = "TestStruct";
      foo<TypedTestDesc<TestStruct>{name}>();
      bar<TypedTestDesc<TestStruct>{name}, TypedTestDesc<TestStruct>{name}>();
    }
    

    Demo