接受对抽象类的 const 引用的 C++ 构造函数无法初始化 std::map

Posted

技术标签:

【中文标题】接受对抽象类的 const 引用的 C++ 构造函数无法初始化 std::map【英文标题】:C++ Constructor that accepts const reference to abstract class can't initialize std::map 【发布时间】:2019-04-24 02:25:01 【问题描述】:

我有一个抽象类 A,它为它在 B 类中的实现定义了一个接口。A 的所有方法都是纯虚拟的。

我的问题是带有签名 B(const A &base) 的 B 的构造函数。我被卡住了......我无法正确复制 std::map 的内容。请参阅下面的更多细节。任何帮助将不胜感激!

struct W 
    W() = default;
;

template<typename T>
struct V : public W 
    V() = default;
;

class A 
public:
    A() = default;
    virtual std::map<std::shared_ptr<const W>, std::any> getFields() const = 0;
;

template<typename T>
class B : public A 
private:
    std::map<std::shared_ptr<const V<T>>, std::any> _fields;
    T _value;

public:

    B(T value) : _value(value) 
    

    explicit B(const A &base) 
        for (std::pair<std::shared_ptr<const W>, std::any> field : base.getFields()) 
            auto key = std::dynamic_pointer_cast<const V<T>>(field.first);
            // the line below does not compile...
            _fields.insert(key, field.second);
          
    

    std::map<std::shared_ptr<const W>, std::any> getFields() const override 
        std::map<std::shared_ptr<const W>, std::any> copy;
        copy.insert(_fields.begin(), _fields.end());
        return copy;
    
;

struct C 
  std::vector<std::shared_ptr<const B<int>>> vec;

  void addElement(const A& element) 
      vec.push_back(std::make_shared<const B<int>>(element));
    
;

【问题讨论】:

【参考方案1】:

std::map::insert() 采用键值对,而不是单独的键和值:

_fields.insert(std::make_pair(key, field.second));

或者,考虑std::map::emplace(),它在映射内部构造键值对:

_fields.emplace(std::move(key), std::move(field.second));

【讨论】:

以上是关于接受对抽象类的 const 引用的 C++ 构造函数无法初始化 std::map的主要内容,如果未能解决你的问题,请参考以下文章

拷贝构造函数详解

拷贝构造函数详解

扩展1

拷贝构造函数详解

boost make_shared接受一个const引用。有办法解决这个问题吗?

如何在 C++ 子类的构造函数中初始化超类的 const 成员变量?