0

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
Bob__
  • 12,361
  • 3
  • 28
  • 42
monamimani
  • 273
  • 2
  • 11
  • typo: `foo()` -> `foo()` – user17732522 Feb 28 '23 at 06:30
  • In `template void foo()`, `TypedTestDesc` is a non-type template parameter - but then you turn around and use it as if it were a type name, `typename TypedTestDesc::Type`. However, on the very next line, you use it as a non-type again, `TypedTestDesc.m_typeName`. Which way is it supposed to be? – Igor Tandetnik Feb 28 '23 at 21:50
  • A string literal cannot be used as a non-type template parameter; and neither can things that depend on it. So `TypedTestDesc{"TestStruct"}` won't work as a template parameter. – Igor Tandetnik Feb 28 '23 at 22:14

1 Answers1

1

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

Igor Tandetnik
  • 50,461
  • 4
  • 56
  • 85