用std::unique_ptr作为值初始化const static std::map

4
这个问题与使用std::unique_ptr作为值初始化静态std::map类似。但是在我的问题中,map应该是只读的。那么,我该如何初始化一个静态的const map,其中值是std::unique_ptr?
static const std::map<int, std::unique_ptr<MyClass>> 

在这种情况下,静态函数内的初始化不起作用。
std::map<int, std::unique_ptr<MyClass>> init()
{
    std::map<int, std::unique_ptr<MyClass>> mp;
    mp[0] = std::make_unique<MyClass>();
    mp[1] = std::make_unique<MyClass>();
    //...etc
    return mp;
}

通过初始化列表进行初始化也不起作用。
    const std::map<int, std::unique_ptr<MyClass>> = {
        { 0, std::make_unique<MyClass>() }

你尝试过使用 const std::map<int, std::unique_ptr<MyClass>> mp = {...} 吗? - felix
首先,您遇到了什么具体的编译错误?其次,请提供您静态常量映射的动机。似乎有更简单的方法来使用其他设计模式实现您的要求。此外,鉴于@felix的评论,我认为您在“通过初始化列表进行初始化...”的描述中存在拼写错误。 - jhill515
初始化列表需要复制构造函数,因此无法与独占指针配合使用。这是在 SO 上已知的问题。 - Matthieu Brucher
可能是如何统一初始化unique_ptr的map?的重复问题。 - Matthieu Brucher
1个回答

5
您不能直接使用std::unique_ptrinitializer list实例化const map,因为:

std::initializer-list构造会复制其内容。

而您无法复制std::unique_ptr


因此,您可以在函数内部“动态”创建映射,并将内容移动到const map中。

即:

using Map = std::map<int, std::unique_ptr<int>>;

static Map GenMap() {
  Map m;
  m[0] = std::make_unique<int>(0);
  // ...
  return m;
}

static const Map globalStaticMap = GenMap();

Lambda可以避免定义静态函数,使你的代码更加简洁。

static const Map globalStaticMap = []() {
  Map m;
  m[0] = std::make_unique<int>(0);
  // ...
  return m;
}();

2
一个立即调用的lambda在这里也非常棒。 - Quentin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接