簡體   English   中英

std::map 持有任何值類型

[英]std::map holding any value type

代碼:

#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保存任何值類型,因此我創建了一個帶有動態 inheritance 的模板 class。 我在MyClass中定義了模板 class ,因為我不希望它的定義暴露給用戶。 使用getType function 我將創建一個具有給定類型的新 object,該類型將存儲到 map 中。

使用上述方法,我得到以下錯誤,我無法使用上述方法成功。

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);
}

然后像這樣使用 function :

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

請注意,您不需要在調用站點指定T ,因為這可以從 function 參數中推斷出來。

當然,您需要跟蹤 map 中的每個鍵分別指的是什么類型。

這是一個演示

此外,實現此 function 的方式,名稱getType令人困惑,因為您實際上並沒有在這里返回類型。 也許更好的名字是getAnyPointer

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM