C++ GCC shared_ptr和make_shared on map separated var类型错误

C++ GCC shared_ptr和make_shared on map separated var类型错误,c++,gcc,shared-ptr,C++,Gcc,Shared Ptr,我想使用std::shared_ptr和std::make_shared并创建一个带有独立变量类型的映射列表。。。我的编译器是GCC,这是我的源代码 #include <iostream> #include <cstring> #include <memory> #include <string> #include <map> using namespace std; class key_base { public: v

我想使用
std::shared_ptr
std::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;
}
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
类密钥库{
公众:
virtual~key_base()=默认值;
key_base()=默认值;
模板常量T&Read();
};
模板
类密钥:公钥{
私人:
T储存;
公众:
密钥(常数和存储){
存储=存储;
}
常量T&Read(){返回存储器}
};
int main(){
地图列表;
列表[0]=std::使_共享(“你好”);
列表[1]=std::共享(“你多大了?”);
列表[2]=std::使_共享(22);
用于(自动此项:列表){
如果(thisItem.first==2)

问题是,您认为动态多态性可以与模板一起工作

基本上,
base_class
中的模板声明
template const&Read();
是完全无用的。 如果使用基类,编译器如何推断应该为
Read()
执行什么操作?这个模板没有定义,编译器也不知道如何到达定义这个方法的子类

您的设计是错误的,由于这是经典的,我们无法帮助您正确解决此问题

看起来您应该看看C++17中的新模板:


要使其正常工作(我讨厌代码设计),您需要在
key
class之后添加缺少的模板定义:

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" };
}
模板
常量T&key_base::Read()
{
if(自动子类对象=动态_转换(此)){
返回SubassObject->Read();
}
抛出域_错误{“无效读取使用”};
}
它对我有用。
它适用于。

带有双下划线的标识符是为实现保留的。在我看来,您只是忘记了将
key\u base
的继承设置为public。私有继承在类外部是不可见的。@FrançoisAndrieux是的。他想要,
class-key:public-key\u base{
。否则,派生是一个实现细节。如果我使用microsoft编译器并将此(template const T&Read())更改为(template const T&Read()=0)我的问题解决了!!!!!!!依赖于VS?试试我的例子,我想知道VS会用它做什么。即使经过修改,它也不会在VS上编译。请再次阅读问题..我更改了它(问题的一部分)