Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fold expression instantiation #336

Closed
coralkashri opened this issue Aug 9, 2020 · 2 comments
Closed

fold expression instantiation #336

coralkashri opened this issue Aug 9, 2020 · 2 comments

Comments

@coralkashri
Copy link

coralkashri commented Aug 9, 2020

A really important issue about fold expressions is the parenthesis. Now, it's not a bug, but a possibility for a wrong understanding of how does fold expression instantiation work. A simple example:

template <typename ...Args>
auto add(Args&& ...args) {
    return (args + ...);
}

int main() {
    add(1, 3, 4);
}

Will produce the following specialization:

template<>
int add<int, int, int>(int && __args0, int && __args1, int && __args2)
{
  return __args0 + (__args1 + __args2);
}

Which is mostly right, at this particularly case- There should be an outer parenthesis, but they are meaningless here. But not in the following case:

template <typename ...Args>
auto add(Args&& ...args) {
    return (args + ...) * 3;
}

For this one, the output will be:

template<>
int add<int, int, int>(int && __args0, int && __args1, int && __args2)
{
  return (__args0 + (__args1 + __args2)) * 3;
}

Which is really nice, but also might fool some students.
Now, I'm not sure who you are targeting with this amazing tool, but I think it might be nice to consider adding the parenthesis, even when they are not fully necessary.

@andreasfertig
Copy link
Owner

Hello @korelkashri,

all issues are important, at least to me. Thanks for reporting this one. The goal is to show correct code which compiles and yields the same result. However, showing "correct" code is not always possible.

You are right, the outer parenthesis are missing. The reason is, that in the instantiation of the function template there are only expressions left like in this case BinaryOperator. Only in the declaration of the primary template I know that this is a fold expression. After that it is guessing and in this case I just leave it as the compiler shows it.

Which is mostly right, at this particularly case- There should be an outer parenthesis, but they are meaningless here. But not in the following case:
template <typename ...Args>
auto add(Args&& ...args) {
return (args + ...) * 3;
}

I'm not sure whether I'm missing something here, but in this case the output is correct, all braces are there. The * 3 part is not part of the fold expression. To create a binary right fold the * 3 must go inside the parenthesis and then must match the first operator.

In summary, the first part is slightly incorrect but yields to the correct result. It will stay that way, except somebody finds a clever way to detect that this was/is part of a fold expression. The second part is in my opinion correct.

Andreas

@andreasfertig andreasfertig added the awaiting-followup Waiting for more input label Aug 10, 2020
@coralkashri
Copy link
Author

coralkashri commented Aug 10, 2020

No, you are right, I showed the second example to show that the behavior is correct, it just doest show the outer parenthesis in case that they aren't require.

@andreasfertig andreasfertig removed the awaiting-followup Waiting for more input label Sep 15, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants