避免在没有原始指针的情况下复制地图的密钥

dan*_*iel 3 c++ smart-pointers stdmap stdstring c++11

每次在std :: map中插入一对,其键是std :: string时,它会生成两个副本.您可以避免使用原始指针,但它是异常不安全的.有没有办法使用智能指针而不是原始指针?

示例代码:

// 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
}
Run Code Online (Sandbox Code Playgroud)

输出:

COPY-CONSTRUCTOR
COPY-CONSTRUCTOR
---
Run Code Online (Sandbox Code Playgroud)

Pup*_*ppy 7

这是低效的,因为你写错了你的课.C++ 0x提供了右值引用 - 你只是编写了你的​​类,因此它无法利用它们.

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;
    }
};
Run Code Online (Sandbox Code Playgroud)

unique_ptr作为关键?这不可能.你永远不可能得到相同的东西unique_ptr- 即使你以某种方式得到相同的指针并unique_ptr从中构造了一个,你也会在比较完成后立即删除密钥.