11

I am learning the new c++17 fold expression and I saw this code from c++17 fold expression. I would like to know why this code work :

template<typename ...Args>
void printer(Args&&... args) {
    (std::cout << ... << args) << '\n';
}

but not this one :

template<typename ...Args>
void printer(Args&&... args) {
    (std::cout << args << ...) << '\n';
}

which could seems logic too and would reverse the print order in my opinion.

ildjarn
  • 62,044
  • 9
  • 127
  • 211
  • `std::cout << ... << args` matches (4) `init op ... op pack`. `std::cout << args << ...` matches none of the valid forms. – Michael Aug 29 '16 at 10:29
  • And why people choose to not create this form ? how then could we get the parameters in a reverse way ? – Gabrielle de Grimouard Aug 29 '16 at 10:39
  • "*how then could we get the parameters in a reverse way ?*" You'd have to write some reversing tool, which would be very difficult to write. Normal pack expansion has no way to expand the pack in reverse order either. – Nicol Bolas Aug 29 '16 at 14:32
  • @NicolBolas Not that difficult... – T.C. Aug 29 '16 at 18:46

1 Answers1

17

As seen on cppreference, binary folds can have the following two forms:

Screenshot from cppreference/fold

Where E is the pack expression and I is the initialization expression.


There is no binary fold that matches your (std::cout << args << ...), which has the form of (I op E op ...).

Vittorio Romeo
  • 90,666
  • 33
  • 258
  • 416
  • 1
    Hi - I am aware this is a long time ago, but could someone shows me what will ```(std::cout << args << ...)``` look like after expanding? I just don't get it no matter how many times I read cppref. It seems like it's going to expand to ```(((std::cout << arg1) << arg2) << arg3)``` which looks totally valid. The other way around would be ```(std::cout << (arg1 << (arg2 << arg3)))``` but it works. HOW??? – Hydrogen Sep 21 '22 at 04:55
  • 1
    @Hydrogen: `I` is `std::cout`, `op` is `<<`, and `E` is `args...`. – Vittorio Romeo Sep 21 '22 at 19:02
  • Thanks for the clarification. I thought the "which" word you mean in your original text referring to ```(std::cout << args << ...)```. – Hydrogen Sep 27 '22 at 02:21