How to use a fold expression to call a chain of member functions

126 views Asked by At

I have a builder class like this

class Builder
{
public:
   Builder (SomeData someData);
   
   template <class FooType, class... FooConstructorArgs>
   Builder&& addFoo (FooConstructorArgs&&... args) &&
   {
      addInternal (new FooType (std::forward<FooConstructorArgs> (args)...);
      return std::move (*this);
   }
//...
}

Now there is a function like this

std::string createUuid();

template <std::constructible_from<std::string> FooType>
void bar (SomeData data)
{
   auto builder = Builder (data).addFoo<FooType> (createUuid());
   
   // do something fancy with that builder
}

However, what I really want is a function signature like this:

template <std::constructible_from<std::string>... FooTypes>
void bar (SomeData data)

Where addFoo is called chained for each type, e.g.

addFoo<Bar, Baz> (data);

// expands internally to
auto builder = Builder (data).addFoo<Bar> (createUuid()).addFoo<Baz> (createUuid());

I'm generally aware of the existence of fold expressions, but I can't figure out the syntax to write this as a fold expression. I'm not even sure if chained member function calls are supported with fold expressions at all. Can someone either give me a hint on how to implement it or confirm that this is indeed impossible?

1

There are 1 answers

0
康桓瑋 On

You can use the comma operator(,) to expand the parameter pack

template <std::constructible_from<std::string>... FooTypes>
void bar (SomeData data)
{
  auto builder = Builder (data);
  ((builder = std::move(builder).addFoo<FooTypes>(createUuid())), ...);
}