std::map 保存任何值类型



Code:

#include <iostream>
#include<map>
using namespace std;
class MyClass {
public:
class MyFieldInterface
{
public:
int m_Size;
~MyFieldInterface() = default;
};
template <typename T>
class MyField : public MyFieldInterface {
public:
MyField(T val) {m_Value = val;}
T m_Value; 
};
template <typename T>
MyField<T>* getType(int type, T val) {
if (type == 0) return new MyField<int>(val);
if (type == 1) return new MyField<double>(val);
if (type == 2) return new MyField<char>(val);
}
map<string, MyFieldInterface* > fields;  
};
int main()
{
MyClass obj;
obj.fields["a"] = obj.getType<int>(0, 1);
obj.fields["b"] = obj.getType<double>(1, 1.1);
obj.fields["c"] = obj.getType<char>(2, 'a');
return 0;
}

问题:

我希望std::map保存任何值类型,因此我创建了一个具有动态继承的模板类。 我已经在MyClass中定义了模板类,因为我不希望它的定义暴露给用户。使用getType函数,我将创建一个具有给定类型的新对象,该对象将存储在地图中。

使用上述方法,我得到以下错误,我无法使用上述方法成功。

main.cpp: In instantiation of ‘MyClass::MyField<T>* MyClass::getType(int, T) [with T = int]’:
<span class="error_line" onclick="ide.gotoLine('main.cpp',45)">main.cpp:45:44</span>:   required from here
main.cpp:34:53: error: cannot convert ‘MyClass::MyField*’ to ‘MyClass::MyField*’ in return
if (type == 1) return new MyField<double>(val);
^
main.cpp:35:51: error: cannot convert ‘MyClass::MyField*’ to ‘MyClass::MyField*’ in return
if (type == 2) return new MyField<char>(val);
^
main.cpp: In instantiation of ‘MyClass::MyField<T>* MyClass::getType(int, T) [with T = double]’:
<span class="error_line" onclick="ide.gotoLine('main.cpp',46)">main.cpp:46:49</span>:   required from here
main.cpp:33:50: error: cannot convert ‘MyClass::MyField*’ to ‘MyClass::MyField*’ in return
if (type == 0) return new MyField<int>(val);
^
main.cpp:35:51: error: cannot convert ‘MyClass::MyField*’ to ‘MyClass::MyField*’ in return
if (type == 2) return new MyField<char>(val);
^
main.cpp: In instantiation of ‘MyClass::MyField<T>* MyClass::getType(int, T) [with T = char]’:
<span class="error_line" onclick="ide.gotoLine('main.cpp',47)">main.cpp:47:47</span>:   required from here
main.cpp:33:50: error: cannot convert ‘MyClass::MyField*’ to ‘MyClass::MyField*’ in return
if (type == 0) return new MyField<int>(val);
^
main.cpp:34:53: error: cannot convert ‘MyClass::MyField*’ to ‘MyClass::MyField*’ in return
if (type == 1) return new MyField<double>(val);
^

不能使用运行时参数在多个类型之间进行选择。您需要决定在编译时返回哪种类型。但这正是模板的用途,所以你可以简单地做:

template <typename T>
MyField<T>* getType(T val) {
return new MyField<T>(val);
}

然后像这样使用函数:

obj.fields["a"] = obj.getType(1);
obj.fields["b"] = obj.getType(1.1);
obj.fields["c"] = obj.getType('a');

请注意,您不需要在调用站点指定T,因为这可以从函数参数中推导出来。

当然,您需要跟踪地图中每个键分别引用的类型。

这是一个演示。

此外,此函数的实现方式,名称getType令人困惑,因为您实际上并没有在此处返回类型。也许更好的名字是getAnyPointer.

最新更新