Avoid copying a card key without raw pointers

Each time you insert a pair into std :: map, whose key is std :: string, it makes two copies. You can avoid using source pointers, but this exception is unsafe. Is there a way to use a smart pointer instead of a raw pointer?

Code example:

// To compile: g++ -std=c++0x exmaple.cpp -o example 

#include <iostream>
#include <string>
#include <map>
#include <memory>

class StringSquealer: public std::string
{
  public:
    StringSquealer(const std::string s) : std::string(s) {}
    StringSquealer(const StringSquealer&) 
    { 
      std::cout << "COPY-CONSTRUCTOR" << std::endl; 
    }
};

int main()
{
  // Inefficient
  std::map<StringSquealer,int> m1;
  m1[StringSquealer("key")] = 1;
  std::cout << "---" << std::endl;

  // Exception-unsafe
  std::map<StringSquealer*,int> m2;
  m2[new StringSquealer("key")] = 1;

  //Ideal??
  std::map<std::unique_ptr<StringSquealer>,int> m3;
  std::unique_ptr<StringSquealer> s(new StringSquealer("key"));
  //!m3[std::move(s)] = 1;  // No compile
}

Conclusion:

COPY-CONSTRUCTOR
COPY-CONSTRUCTOR
---
+3
source share
3 answers

This is inefficient because you have spelled your class incorrectly. C ++ 0x provides links to rvalue - you just wrote your class so that it could not use them.

class StringSquealer: public std::string
{
  public:
    StringSquealer(std::string&& s) : std::string(std::move(s)) {}
    StringSquealer(const std::string& s) : std::string(s) {}
    StringSquealer(const StringSquealer& s)
        : std::string(s) 
    { 
      std::cout << "COPY-CONSTRUCTOR" << std::endl; 
    }
    StringSquealer(StringSquealer&& s)
        : std::string(std::move(s)) 
    {
        std::cout << "MOVE-CONSTRUCTOR" << std::endl;
    }
};

unique_ptr ? . unique_ptr, unique_ptr, , .

+7

- , - , uless, , , . , , , , .

unique_ptr , , . , , unique_ptr. , , unique_ptrs, , . , , , , , -, . .

, , --. , O (1), , , . , , , , .

+2

:

  • std::string
  • unique_ptr

shared_ptr , .

std::string , , .

By the way, the most expensive part of copying is distribution rather than copying itself. For this, you can consider using basic_string with a special allocator.

+1
source

Source: https://habr.com/ru/post/1790333/


All Articles