Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Special Interest Groups
  3. C++ Gurus
  4. Passing function as universal reference? Why?

Passing function as universal reference? Why?

Scheduled Pinned Locked Moved Unsolved C++ Gurus
c++universal refrvaluetemplate
3 Posts 3 Posters 1.3k Views
  • 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 26 Jan 2018, 08:35 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 26 Jan 2018, 09:57
    0
    • V Offline
      V Offline
      VRonin
      wrote on 26 Jan 2018, 09:03 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
        26 Jan 2018, 08:35

        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 26 Jan 2018, 09:57 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

        1/3

        26 Jan 2018, 08:35

        • Login

        • Login or register to search.
        1 out of 3
        • First post
          1/3
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved