Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Special Interest Groups
  3. C++ Gurus
  4. Passing function as universal reference? Why?
Qt 6.12 LTS is out! See what's new in the release blog

Passing function as universal reference? Why?

Scheduled Pinned Locked Moved Unsolved C++ Gurus
c++universal refrvaluetemplate
3 Posts 3 Posters 2.4k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • K Offline
    K Offline
    Kofr
    wrote on last edited by Kofr
    #1

    Why Functor&& f is possed as universal ref? this is the function, when the function can become a rvalue?

    /**
           *  Calls function <code>f</code> in this thread and returns a future<T> that can
           *  be used to wait on the result.  
           *
           *  @param f the operation to perform
           *  @param prio the priority relative to other tasks
           */
          template<typename Functor>
          auto async( Functor&& f, const char* desc FC_TASK_NAME_DEFAULT_ARG, priority prio = priority()) -> fc::future<decltype(f())> {
             typedef decltype(f()) Result;
             typedef typename fc::deduce<Functor>::type FunctorType;
             fc::task<Result,sizeof(FunctorType)>* tsk = 
                  new fc::task<Result,sizeof(FunctorType)>( fc::forward<Functor>(f), desc );
             fc::future<Result> r(fc::shared_ptr< fc::promise<Result> >(tsk,true) );
             async_task(tsk,prio);
             return r;
          }
    
    K 1 Reply Last reply
    0
    • VRoninV Offline
      VRoninV Offline
      VRonin
      wrote on last edited by VRonin
      #2

      Take this functor:

      class ExampleFunctor
      {
          int* m_longArray;
          int m_longArraySize;
      public:
          ExampleFunctor(int sz = 10000)
              :m_longArraySize(sz)
          {
              if (m_longArraySize < 10000) m_longArraySize = 10000;
              m_longArray = new int[m_longArraySize];
              for (int i = 0; i < m_longArraySize; ++i)
                  m_longArray[i] = rand();
          }
          ~ExampleFunctor() { if (m_longArray) delete[] m_longArray; }
          ExampleFunctor(const ExampleFunctor& other)
              :m_longArraySize(other.m_longArraySize)
              , m_longArray(new int[other.m_longArraySize])
          {
              for (int i = 0; i < m_longArraySize; ++i)
                  m_longArray[i] = other.m_longArray[i];
          }
          ExampleFunctor(ExampleFunctor&& other)
              :m_longArraySize(other.m_longArraySize)
              , m_longArray(other.m_longArray)
          {
              other.m_longArray = nullptr;
          }
          ExampleFunctor& operator=(ExampleFunctor&& other)
          {
              m_longArraySize = other.m_longArraySize;
              std::swap(other.m_longArray, m_longArray);
              return *this;
          }
          ExampleFunctor& operator=(const ExampleFunctor& other)
          {
              if (m_longArray) delete[] m_longArray;
              m_longArraySize = other.m_longArraySize;
              m_longArray = new int[m_longArraySize];
              for (int i = 0; i < m_longArraySize; ++i)
                  m_longArray[i] = other.m_longArray[i];
              return *this;
          }
          int operator()()
          {
              int result = 0;
              for (int i = 0; i < m_longArraySize - 1; ++i)
                  result += (m_longArray[i] ^= m_longArray[i + 1]);
              return result;
          }
          static ExampleFunctor createFunctor(int size) { return ExampleFunctor(size); }
      };
      

      Pass it to your template async(ExampleFunctor::createFunctor(1000000));

      Let's see what happens in each case:

      • auto async(Functor f : takes a deep copy of the functor
      • auto async(const Functor& f : if you want to call the functor (since it's not const) you'll have to take a deep copy of it sooner or later
      • auto async(Functor& f: this would work in the example above but if operator()() was const and you create it with const ExampleFunctor temp(1000000); then you can't pass it anymore
      • auto async(Functor&& f: accepts all kind of arguments without compromising efficiency

      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
      ~Napoleon Bonaparte

      On a crusade to banish setIndexWidget() from the holy land of Qt

      1 Reply Last reply
      3
      • K Kofr

        Why Functor&& f is possed as universal ref? this is the function, when the function can become a rvalue?

        /**
               *  Calls function <code>f</code> in this thread and returns a future<T> that can
               *  be used to wait on the result.  
               *
               *  @param f the operation to perform
               *  @param prio the priority relative to other tasks
               */
              template<typename Functor>
              auto async( Functor&& f, const char* desc FC_TASK_NAME_DEFAULT_ARG, priority prio = priority()) -> fc::future<decltype(f())> {
                 typedef decltype(f()) Result;
                 typedef typename fc::deduce<Functor>::type FunctorType;
                 fc::task<Result,sizeof(FunctorType)>* tsk = 
                      new fc::task<Result,sizeof(FunctorType)>( fc::forward<Functor>(f), desc );
                 fc::future<Result> r(fc::shared_ptr< fc::promise<Result> >(tsk,true) );
                 async_task(tsk,prio);
                 return r;
              }
        
        K Offline
        K Offline
        Konstantin Tokarev
        wrote on last edited by
        #3

        BTW, keep in mind that there is no such thing as "universal ref" in C++ standard. It's just a way of thinking about rvalue ref T&& in contexts which provide type deduction for T

        1 Reply Last reply
        1

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt
        • Unsolved