Advertisement
ascend4nt

initializer_list proxy function – insert iterator version

Jan 11th, 2013
279
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.96 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <string>
  4. #include <utility>
  5. #include <iterator>
  6. #include <initializer_list>
  7.  
  8. // initializer_list proxy function – insert iterator version
  9. // Author: Ascend4nt
  10. // https://ascend4nt.wordpress.com/2013/01/11/initializer_list-proxy-function-insert-iterator-version/
  11.  
  12. // A simple (incomplete) wrapper for string objects which is used to demonstrate
  13. // how initializer_lists work with objects
  14. class StringHolder{
  15. protected:
  16.     std::string myStr;
  17. public:
  18.     StringHolder() : myStr()
  19.         { std::cout << "StringHolder empty constructor" << std::endl; }
  20.     StringHolder(const char* sInit) : myStr(sInit)
  21.         { std::cout << "StringHolder(const char*) constructor, init string: " << sInit << std::endl; }
  22.     // Copy-construct
  23.     StringHolder(const StringHolder & copyFrom) : myStr(copyFrom.myStr)
  24.         { std::cout << "StringHolder (*COPY*) Constructor called, made COPY of: " << myStr << std::endl; }
  25.     // Move-construct
  26.     StringHolder(StringHolder && moveFrom) noexcept
  27.      : myStr(std::move(moveFrom.myStr))
  28.     {
  29.         // Note we already move-constructed string myStr, which has its own move constructor
  30.         std::cout << "StringHolder (*MOVE*) Constructor called, now owning: " << myStr << std::endl;
  31.     }
  32.     ~StringHolder()
  33.     { std::cout << "~StringHolder ~destructor~, string contents: " << myStr << std::endl; }
  34.    
  35.     // Copy-Assignment
  36.     StringHolder& operator=(const StringHolder& copyFrom)
  37.     {
  38.         // Make sure we are not assigning to ourself
  39.         if (this != &copyFrom)
  40.         {
  41.             /* Clear our values, release resources */
  42.             myStr.clear();
  43.             /* Copy in new values/resources */
  44.             myStr = copyFrom.myStr;
  45.  
  46.             std::cout << "StringHolder operator=(COPY) called, made COPY of: " << myStr << std::endl;
  47.         }
  48.         return *this;
  49.     }
  50.     // Move-Assignment
  51.     StringHolder& operator=(StringHolder&& moveFrom) noexcept
  52.     {
  53.         // Make sure we are not assigning to ourself
  54.         if (this != &moveFrom)
  55.         {
  56.             // Move-assign myStr (we invoke it via operator= just so we're clear on the std::move() definition
  57.             myStr.operator=(std::move(moveFrom.myStr));
  58.  
  59.             std::cout << "StringHolder operator=(MOVE) called, now owning: " << myStr << std::endl;
  60.         }
  61.         return *this;
  62.     }
  63. };
  64.  
  65.  
  66. // initializer_list Proxy - Using Insert Iterators
  67. template <typename InsIter, typename LType>
  68. void insertInitListProxy(InsIter inserter, std::initializer_list<LType> il)
  69. {
  70.     // construct & move the items into the container
  71.     for (auto it = il.begin(); it < il.end(); ++it)
  72.         *inserter++ = *it;
  73. }
  74.  
  75.  
  76. int main ()
  77. {
  78.     std::vector<StringHolder> myVec;
  79.    
  80.     // Reserve some space so no vector resizing takes place
  81.     myVec.reserve(20);
  82.    
  83.     // Create a back_insert_iterator for our vector
  84.     std::back_insert_iterator<std::vector<StringHolder>> myIns(myVec);
  85.    
  86.     std::cout << "---------- Pushing data on vector ----------\n" << std::endl;
  87.    
  88.     // Traditional method of adding data
  89.     *myIns++ = "strA";
  90.     *myIns++ = "strB";
  91.    
  92.     // Alternate means of adding data - do NOT use in your code!
  93.     //  (only meant to demonstrate what happens)
  94.     myIns= "strC"; // calls push_back()
  95.     myIns= "strD"; // and again
  96.  
  97.     std::cout << "\n------ Now invoking initializer_list insertion ------\n" << std::endl;
  98.  
  99.     myVec.insert(myVec.end(), {"str1", "str2"});
  100.  
  101.     std::cout << "\n------ Now invoking initializer_list proxy ------\n" << std::endl;
  102.  
  103.     // Here we could pre-allocate the needed space before the call,
  104.     // though it's not very intuitive:
  105.     //myVec.reserve(myVec.size() + 3);
  106.  
  107.     // insert_iterator version of the 'other' initializer_list Proxy:
  108.     insertInitListProxy(std::back_inserter(myVec), {"str3", "str4", "str5"});
  109.  
  110.     std::cout << "\n---------- Vector Destruction looming ----------\n" << std::endl;
  111.  
  112.     return 0;
  113. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement