std::future as a parameter to a function C++

There can be only one future. You cannot have multiple copies of the same future. So you need to transfer ownership of the future to the function:

printPromised(std::move(f));
//            ^^^^^^^^^^^^

If you genuinely need shared access to a future, you can construct a shared_future from an ordinary future by calling the share() member function; this behaves similarly to a shared pointer:

auto sf = std::async(std::launch::async, [](){ return 8; }).share();

Now sf can be copied, and all copies wait for the same result, i.e. the wait() calls on all copies may block and will synchronize with the becoming-ready of the result.