fix: make factory functions use std::move instead of std::forward #45
+399
−170
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
@nathanhhughes
Unfortunately, my previous PR #44, while adding support for move only types, actually ended up introducing a bug where l-values end up being casted to r-value references. This casting then makes the factory function lookup fail. The following unit test looks like it should work, but doesn't actually pass after #44. The reason the PR unit tests pass is because all the factory unit tests were written with r-values and no l-values.
With the error being:
My understanding here is that the function signature with the forwarding reference
&&
below causes the incorrect type to be deduced.The type of
args
ends up being deduced asint&
through reference collapsing rules, which then ends up causing a factory method lookup failure later. As proof of this theory, we can actually make the test pass by casting to i to int. Or explicitly specifyingConstructorArguments
andstd::move
'ingi
to allow the r-value reference to bind toi
.The fix
This PR fixes the issue by first reverting the previous commit, and then adding
std::move
instead ofstd::forward
everywhere the args are used. Several unit tests are added to ensure r-value, r-value reference, l-value, const l-value and move only types work correctly.