Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8972833
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 15, 20262026-06-15T18:18:46+00:00 2026-06-15T18:18:46+00:00

I have a function template, where I want to do perfect forwarding into a

  • 0

I have a function template, where I want to do perfect forwarding into a lambda that I run on another thread. Here is a minimal test case which you can directly compile:

#include <thread>
#include <future>
#include <utility>
#include <iostream>
#include <vector>

/**
 * Function template that does perfect forwarding to a lambda inside an
 * async call (or at least tries to). I want both instantiations of the
 * function to work (one for lvalue references T&, and rvalue reference T&&).
 * However, I cannot get the code to compile when calling it with an lvalue.
 * See main() below.
 */
template <typename T>
std::string accessValueAsync(T&& obj)
{

    std::future<std::string> fut =
        std::async(std::launch::async,
            [](T&& vec) mutable
            {
                return vec[0];
            },
            std::forward<T>(obj));

    return fut.get();
}

int main(int argc, char const *argv[])
{
    std::vector<std::string> lvalue{"Testing"};

    // calling with what I assume is an lvalue reference does NOT compile
    std::cout << accessValueAsync(lvalue) << std::endl;

    // calling with rvalue reference compiles
    std::cout << accessValueAsync(std::move(lvalue)) << std::endl;

    // I want both to compile.

    return 0;
}

For the non-compiling case, here is the last line of the error message which is intelligible:

main.cpp|13 col 29| note:   no known conversion for argument 1 from ‘std::vector<std::basic_string<char> >’ to ‘std::vector<std::basic_string<char> >&’

I have a feeling it may have something to do with how T&& is deduced, but I can’t pinpoint the exact point of failure and fix it. Any suggestions?

Thank you!

EDIT: I am using gcc 4.7.0 just in case this could be a compiler issue (probably not)

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-15T18:18:47+00:00Added an answer on June 15, 2026 at 6:18 pm

    The way I understand it you cannot use a function through async that expects non-const lvalue references as arguments, because async will always make a copy of them internally (or move them inside) to ensure they exist and are valid throughout the running time of the thread created.

    Specifically, the Standard says about async(launch policy, F&& f, Args&&... args):

    (§30.6.8)

    (2) Requires: F and each Ti in Args shall satisfy the MoveConstructible requirements. INVOKE(DECAY_COPY (std::forward<F>(f)), DECAY_COPY (std::forward<Args>(args))...) (20.8.2, 30.3.1.2) shall be a valid expression.

    (3) Effects: […] if policy & launch::async is non-zero — calls INVOKE(DECAY_COPY (std::forward<F>(f)),DECAY_COPY (std::forward<Args>(args))...) (20.8.2, 30.3.1.2) as if in a new thread of execution represented by a thread object with the calls to DECAY_COPY() being evaluated in the thread that called async. Any return value is stored as the result in the shared state. Any exception propagated from the execution of INVOKE (DECAY_COPY (std::forward(f)), DECAY_COPY (std::forward(args))…) is stored as the exceptional result in the shared state.
    The thread object is stored in the shared state and affects the behavior of any asynchronous
    return objects that reference that state.

    Unfortunately, this means you cannot even replace the reference with a std::reference_wrapper, because the latter isn’t move-constructible. I suppose using a std::unique_ptr instead of the reference would work (implying, however, that your function arguments will always live on the heap).

    (EDIT/CORRECTION)
    I was working on a related problem when I realized that std::reference_wrapper actually enables a workaround, although I claimed the opposite above.

    If you define a function that wraps lvalue references in a std::reference_wrapper, but leaves rvalue references unchanged, you can pass the T&& argument through this function before handing it over to std::async. I have called this special wrapper function wrap_lval below:

    #include <thread>
    #include <future>
    #include <utility>
    #include <iostream>
    #include <vector>
    #include <type_traits>
    
    /* First the two definitions of wrap_lval (one for rvalue references,
       the other for lvalue references). */
    
    template <typename T>
    constexpr T&&
    wrap_lval(typename std::remove_reference<T>::type &&obj) noexcept
    { return static_cast<T&&>(obj); }
    
    template <typename T>
    constexpr std::reference_wrapper<typename std::remove_reference<T>::type>
    wrap_lval(typename std::remove_reference<T>::type &obj) noexcept
    { return std::ref(obj); }
    
    
    /* The following is your code, except for one change. */
    template <typename T>
    std::string accessValueAsync(T&& obj)
    {
    
      std::future<std::string> fut =
        std::async(std::launch::async,
               [](T&& vec) mutable
               {
                 return vec[0];
               },
               wrap_lval<T>(std::forward<T>(obj)));   // <== Passing obj through wrap_lval
    
      return fut.get();
    }
    
    int main(int argc, char const *argv[])
    {
      std::vector<std::string> lvalue{"Testing"};
    
      std::cout << accessValueAsync(lvalue) << std::endl;
    
      std::cout << accessValueAsync(std::move(lvalue)) << std::endl;
    
      return 0;
    }
    

    With this change, both calls to accessValueAsync compile and work. The first one, which uses an lvalue reference, automatically wraps it in a std::reference_wrapper. The latter is automatically converted back to an lvalue reference when std::async calls the lambda function.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Say I have a template function in namespace A. I also have another namespace
I have some template function and I want to call it using define in
I want to write a template function that checks some Timestamp property (class inherits
I want to have a function with interface like this: template<typename T, typename R>
I have a (free) function template that looks like this template <typename T> T
I have a template function in C++ that basically writes values to an XML
I have a function template that must be allow only certain types. I've seen
I have a template function and wish to ensure at compile time that it
If I have a function template that has a template parameter by value or
I have template function compare defined as below. #include<iostream> using namespace std; template<typename T>

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.