when_all not accepting the documented template arguments
Issue #396
resolved
when_all does not appear to be accepting the documented template arguments.
Latest development spec for when_all:
Test program:
#include <upcxx/upcxx.hpp>
using namespace upcxx;
int main() {
upcxx::init();
future<int> f = make_future(1);
future<int,int> f2 = when_all(f,f);
future<int,int> f3 = when_all<future<int>,future<int>>(f,f);
upcxx::finalize();
return 0;
}
Compile errors (dirac/gcc-10.2/ibv/seq/debug): upcxx-2020.3.7-1-g c3da283
whenall-bug.cc: In function 'int main()':
whenall-bug.cc:11:61: error: no matching function for call to 'when_all<upcxx::future<int>, upcxx::future<int> >(upcxx::future<int>&, upcxx::future<int>&)'
11 | future<int,int> f3 = when_all<future<int>,future<int>>(f,f);
| ^
In file included from /usr/local/pkg/upcxx-dirac/gcc-10.2.0/nightly-2020.07.28/upcxx.debug.gasnet_seq.ibv/include/upcxx/future.hpp:11,
from /usr/local/pkg/upcxx-dirac/gcc-10.2.0/nightly-2020.07.28/upcxx.debug.gasnet_seq.ibv/include/upcxx/backend.hpp:5,
from /usr/local/pkg/upcxx-dirac/gcc-10.2.0/nightly-2020.07.28/upcxx.debug.gasnet_seq.ibv/include/upcxx/allocate.hpp:8,
from /usr/local/pkg/upcxx-dirac/gcc-10.2.0/nightly-2020.07.28/upcxx.debug.gasnet_seq.ibv/include/upcxx/upcxx.hpp:5,
from whenall-bug.cc:1:
/usr/local/pkg/upcxx-dirac/gcc-10.2.0/nightly-2020.07.28/upcxx.debug.gasnet_seq.ibv/include/upcxx/future/when_all.hpp:68:39: note: candidate: 'upcxx::detail::when_all_return_t<ArgFu ...> upcxx::when_all(ArgFu&& ...) [with ArgFu = {upcxx::future1<upcxx::detail::future_kind_shref<upcxx::detail::future_header_ops_general, false>, int>, upcxx::future1<upcxx::detail::future_kind_shref<upcxx::detail::future_header_ops_general, false>, int>}; upcxx::detail::when_all_return_t<ArgFu ...> = upcxx::future1<upcxx::detail::future_kind_when_all<upcxx::future1<upcxx::detail::future_kind_shref<upcxx::detail::future_header_ops_general, false>, int>, upcxx::future1<upcxx::detail::future_kind_shref<upcxx::detail::future_header_ops_general, false>, int> >, int, int>]' (near match)
68 | detail::when_all_return_t<ArgFu...> when_all(ArgFu &&...arg) {
| ^~~~~~~~
/usr/local/pkg/upcxx-dirac/gcc-10.2.0/nightly-2020.07.28/upcxx.debug.gasnet_seq.ibv/include/upcxx/future/when_all.hpp:68:39: note: conversion of argument 2 would be ill-formed:
whenall-bug.cc:11:60: error: cannot bind rvalue reference of type 'upcxx::future1<upcxx::detail::future_kind_shref<upcxx::detail::future_header_ops_general>, int>&&' to lvalue of type 'upcxx::future<int>' {aka 'upcxx::future1<upcxx::detail::future_kind_shref<upcxx::detail::future_header_ops_general>, int>'}
11 | future<int,int> f3 = when_all<future<int>,future<int>>(f,f);
| ^
In file included from /usr/local/pkg/upcxx-dirac/gcc-10.2.0/nightly-2020.07.28/upcxx.debug.gasnet_seq.ibv/include/upcxx/future.hpp:11,
from /usr/local/pkg/upcxx-dirac/gcc-10.2.0/nightly-2020.07.28/upcxx.debug.gasnet_seq.ibv/include/upcxx/backend.hpp:5,
from /usr/local/pkg/upcxx-dirac/gcc-10.2.0/nightly-2020.07.28/upcxx.debug.gasnet_seq.ibv/include/upcxx/allocate.hpp:8,
from /usr/local/pkg/upcxx-dirac/gcc-10.2.0/nightly-2020.07.28/upcxx.debug.gasnet_seq.ibv/include/upcxx/upcxx.hpp:5,
from whenall-bug.cc:1:
/usr/local/pkg/upcxx-dirac/gcc-10.2.0/nightly-2020.07.28/upcxx.debug.gasnet_seq.ibv/include/upcxx/future/when_all.hpp:75:11: note: candidate: 'template<class ArgFu> ArgFu&& upcxx::when_all(ArgFu&&)'
75 | ArgFu&& when_all(ArgFu &&arg) {
| ^~~~~~~~
/usr/local/pkg/upcxx-dirac/gcc-10.2.0/nightly-2020.07.28/upcxx.debug.gasnet_seq.ibv/include/upcxx/future/when_all.hpp:75:11: note: template argument deduction/substitution failed:
whenall-bug.cc:11:61: error: wrong number of template arguments (2, should be 1)
11 | future<int,int> f3 = when_all<future<int>,future<int>>(f,f);
| ^
Comments (3)
-
-
Just to add an explanation of the compiler error, instantiating
when_all<future<int>,future<int>>
forces the function parameters to be rvalue references, while the arguments are lvalues. -
- changed status to resolved
Spec updated to match the implementation in spec PR 50.
- Log in to comment
The implementation takes its arguments by universal reference, which differs from the by-value arguments in the spec. We need to fix this discrepancy.
Summarizing from a Slack discussion with @Dan Bonachea , he would like to construct a
future<int&>
by explicitly instantiatingwhen_all
with template arguments. I do not believe this to be possible given that it takes arguments by universal reference. We can’t tell what the user intent is from the argument type being an lvalue reference. Maybe they want a reference inside a future, maybe they just want to avoid a copy when callingwhen_all
, or maybe they just happened to pass an lvalue towhen_all
without thinking about it.The workaround is to explicitly call
make_future
in this case. I don’t think this will be a common case.