如何使用模板缓存(存储)shared_ptr与类?

时间:2017-02-20 05:09:21

标签: c++ c++11

我正在使用模板重写一个类。在代码如下所示之前。

更改是向bar类添加模板。但是,更改后,缓存映射不起作用,因为我无法确定实际bar类类型的类型。

有没有一种简单的方法来解决这个问题(例如现有的样本/编码模式)?

或者我需要尝试继承创建一个虚拟bar_base并存储父shared_ptr并每次都进行向上/向下投射?如果是这样,我是否还需要将模板类型计算为地图键?

提前致谢。

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

namespace foo {
  class bar {
    public:
    int m_key;
    bar(int key) : m_key(key) {}
  };
  static std::map<int, std::shared_ptr<bar>> cache;
  static std::shared_ptr<bar> create(int key) {
    if (cache.find(key) != cache.end()) {
      std::cout << "cache used" << std::endl;
      return cache[key];
    } else {
      auto p     = std::make_shared<bar>(bar(key));
      cache[key] = p;
      return p;
    }
  }
};

int main(int argc, char * argv[]) {
  foo::create(1);
  foo::create(1);
  foo::create(1);
  return 0;
}

编辑(更新): 以下是要计划的变更:

1将模板添加到栏类

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

namespace foo {

template <typename T = std::string>
class bar {
    public:
    int m_key;
    T   m_dummy;
    bar(int key, T var) : m_key(key), m_dummy(var) {}
};

// static std::map<int, std::shared_ptr<bar>> cache;

template <typename T = std::string>
static std::shared_ptr<bar<T>> create(int key, T var) {
    //if (cache.find(key) != cache.end()) {
        //std::cout << "cache used" << std::endl;
        //return cache[key];
    //}
    //else {
        auto p = std::make_shared<bar<T>>(bar<T>(key, var));
        //cache[key] = p;
        return p;
    //}
}
};

class mystring {
    public:
    mystring(std::string x) {

    }
};

int main(int argc, char * argv[]) {
    auto a = foo::create<std::string>(1, "aaa");
    auto b = foo::create<std::string>(1, "bbb");
    auto c = foo::create<std::string>(1, "ccc");
    auto d = foo::create<mystring>(1,mystring("ddd"));
    return 0;
}

2调整缓存/创建地图。怎么样?

1 个答案:

答案 0 :(得分:0)

在google上进行一些搜索后,我找到了一个解决方案,希望这对有相同要求的人有所帮助。

#include <iostream>
#include <map>
#include <memory>
#include <typeindex>
#include <typeinfo>

namespace foo {

class bar_base {
};
template <typename T = std::string>
class bar : public bar_base {
    public:
    int m_key;
    T   m_dummy;
    bar(int key, T var) : m_key(key), m_dummy(var) {}
};

static std::map<std::pair<std::type_index, int>, std::shared_ptr<bar_base>> cache;

template <typename T = std::string>
static std::shared_ptr<bar<T>> create(int key, T var) {
    if (cache.find(std::pair<std::type_index, int>(typeid(T), key)) != cache.end()) {
        std::cout << "cache used" << std::endl;
        return std::static_pointer_cast<bar<T>>(cache[std::pair<std::type_index, int>(typeid(T), key)]);
    }
    else {
        auto p = std::make_shared<bar<T>>(bar<T>(key, var));
        cache[std::pair<std::type_index, int>(typeid(T), key)] = p;
        return p;
    }
}
};

class mystring {
    public:
    mystring(std::string x) {
    }
};

int main(int argc, char * argv[]) {
    auto a = foo::create<std::string>(1, "aaa");
    auto b = foo::create<std::wstring>(1, L"bbb");
    auto c = foo::create<std::string>(1, "ccc");
    auto d = foo::create<mystring>(1, mystring("ddd"));
    return 0;
}