On Mon, Nov 9, 2020 at 5:15 PM Jason McKesson via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
On Mon, Nov 9, 2020 at 3:19 PM Frank Zingsheim via Std-Proposals
<std-proposals@lists.isocpp.org> wrote:
>
> Hello Barry and Jason
>
> I was confused by the `template` keyword in front of the `for...` which
> I did not find in the proposal.

R0 of the proposal had two variations of `for` loops; R1 combined the
two into `for...`. And the general consensus is that R2 of the
proposal will rename `for...` to be `template for`.

Right. 

There's really two kinds of potential iteration: over an object (whether a tuple or a constexpr range) and over a pack. The expansion statements presented in the paper have an ambiguity in certain cases between whether it's a pack being iterated over or not.

We can avoid the ambiguity by simply having two differently spelled language facilities: one which iterates over an object (spelled "template for") and the other of which iterates over packs (spelled "for ...", because packs). In the translator example, you would use the latter version, which would be spelled the way I said in my earlier email:

template <class... translators>
std::string translate_to_english(std::string_view language, std::string_view text)
{
    for ... {
        if (language == translators::language) {
            return translators::translate_to_english(text);
        }
    }
    throw std::invalid_argument(std::format("Unknown language: {}", language));
}

Note that there's no ()s here for the for, since we wouldn't really need it for this kind of iteration.

Now, even if we didn't get both kinds of expansion statement, if we just got the "template for" spelling, we could still use that to iterate over the types of the translators (just the translators, we don't need to make a tuple of tuples):

template <class... translators>
std::string translate_to_english(std::string_view language, std::string_view text)
{
    template for (auto translator : std::tuple(translators{}...)) {
        if (language == translator.language) {
            return translator.translate_to_english(text);
        }
    }
    throw std::invalid_argument(std::format("Unknown language: {}", language));
}

Barry