地图上的GCC shared_ptr和make_shared分隔var类型错误

时间:2017-10-20 18:49:33

标签: c++ gcc shared-ptr

我想使用std::shared_ptrstd::make_shared并创建一个带有分隔变量类型的地图列表...我的编译器是GCC,这是我的来源

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

using namespace std;

class key_base {

public:

    virtual ~key_base() = default;
    key_base() = default;
    template <typename T> const T & Read();
};

template <typename T>
class key : public key_base {

private:

    T storage_;

public:

    key(const T & __storage) {
        storage_ = __storage;
    }
    const T & Read() { return storage_; }
};

int main() {

    map <int, std::shared_ptr <key_base>> List;

    List[0] = std::make_shared <key<string>>("Hello");
    List[1] = std::make_shared <key<string>>("How old are you?");
    List[2] = std::make_shared <key<int>>(22);


    for (auto thisItem : List) {
        if(thisItem.first == 2)
            cout << thisItem.first << "= (" << thisItem.second->Read<int>() << ")" << endl;
        else
            cout << thisItem.first << "= (" << thisItem.second->Read<string>() << ")" << endl;
    }
    return 0;
}

我知道关于key_base (Read)函数的一件事需要是虚拟的并且= 0并且它必须是模板(以获得var的类型)并且它在GCC中是不可能的(但可能在Microsoft Compiler中)。我该怎么做呢?

1 个答案:

答案 0 :(得分:0)

问题是您认为动态多态将适用于模板。

基本上template <typename T> const T & Read();中的模板声明base_class完全没用。 如果使用基类,您认为编译器如何推断Read()应该做什么?没有此模板的定义,编译器也不知道如何在定义此方法的情况下访问子类。

您的设计错误,因为这是经典XY problem,我们无法帮助您妥善解决此问题。

看起来你应该看看C ++ 17中的新模板: std::any

<小时/> 为了使其工作(我讨厌代码设计),您需要在key类之后添加缺少的模板定义:

template <typename T>
const T & key_base::Read()
{
    if (auto subClassObject = dynamic_cast<key<T> *>(this)) {
        return subClassObject->Read();
    }
    throw domain_error { "Invalid Read use" };
}

适用于Visual Studio。 它适用于GCC