1. 程式人生 > 其它 >c++ 模板 型別相容int和string

c++ 模板 型別相容int和string

在模板函式裡面,一個函式裡面你想一個T typ同時賦值多種型別時,編譯器肯定會提示無法轉換的問題,即使使用static_cast也只能同類型的進行轉換。

T typ;

typ = 3;

typ = "abc"; //這裡會提示問題error:cannot convert ‘std::string’ {aka ‘std::__cxx11::basic_string<char>’} to ‘int’ in assignment

所有使用的技巧就是考慮同一個函式進行型別過載,這樣保證在識別T時,可以轉換至對應的過載函式進行相應處理。即使型別不一樣。

同時將賦值全部歸於一個操作過載函式進行處理,總之是避免在模板函式裡面出現兩種不一樣型別的資料進行寫入或讀取即可。

  1 #include <iostream>
  2 #include <string>
  3 #include <vector>
  4 
  5 #include <array>
  6 #include <list>
  7 #include <memory>
  8 #include <string>
  9 
 10 class GType {
 11     public:
 12         enum class status:uint8_t {
 13             tSuccess = 0
, 14 tGeneralError, 15 tNotFount 16 }; 17 18 enum class Type:uint8_t { 19 tUnkown = 0, 20 tFloat, 21 kDouble, 22 tInt32, 23 tString, 24 tBinary, 25 tBoolean, 26 tObject
27 }; 28 29 public: 30 //GType(const GType rhs) = default; 31 //virtural ~GType() = default; 32 33 GType() noexcept(false); 34 35 GType(int32_t value) noexcept(false) : m_Type(Type::tInt32) {m_ValueInt = value;} 36 GType(uint32_t value) noexcept(false); 37 38 GType(const std::string& value) noexcept(false) : m_Type(Type::tString) {m_ValueString = value;} 39 GType(const char * value) noexcept(false); 40 41 GType(const void *data, std::size_t len) noexcept(false); 42 43 Type GetType() const noexcept {return m_Type;} 44 45 int32_t GetInt() const noexcept(false) { return m_ValueInt; } 46 void SetInt(const int32_t& val) noexcept(false) { m_ValueInt = val; } 47 uint32_t GetUint() const noexcept(false); 48 49 std::string GetString() const noexcept(false) { return m_ValueString; } 50 void SetString(const std::string& val) noexcept(false) { m_ValueString = val; } 51 52 std::string GetBinary(void *data, std::size_t len) const noexcept(false); 53 54 void SetValue(int32_t &val) noexcept(false) {val = m_ValueInt;} 55 void SetValue(std::string &val) noexcept(false) {val = m_ValueString;} 56 57 private: 58 Type m_Type; 59 int32_t m_ValueInt; 60 std::string m_ValueString; 61 }; 62 63 template<typename T> 64 class Result { 65 public: 66 using value_type = T; 67 68 public: 69 Result(T const& t) : m_hasvalue{true}, m_value{std::make_unique<T>(t) } {} 70 Result(T&& t) : m_hasvalue{true}, m_value{std::make_unique<T>(std::move(t))} {} 71 72 T const& operator*() const { return *operator->(); } 73 T const* operator->() const { return &get_value(); } 74 75 T const& Value() const& {return operator*();} 76 T&& Value() && { return std::move(this->get_value()); } 77 78 static Result GetResult(T const &t) {return Result(t); } 79 static Result GetResult(T&& t) {return Result(t);} 80 81 bool HasValue() const noexcept {return m_hasvalue;} 82 private: 83 bool m_hasvalue{false}; 84 std::unique_ptr<T> m_value{nullptr}; 85 86 private: 87 T& get_value() {return *m_value; } 88 T const& get_value() const {return *m_value; } 89 }; 90 91 template <typename T> 92 int32_t GetVal(const std::string& key, T& value) 93 { 94 GType g(value); 95 96 GType::Type typ = g.GetType(); 97 if (typ == GType::Type::tInt32) { 98 g.SetInt(3); 99 printf("That's Int32. value(%d)\n", g.GetInt()); 100 //value = g.GetInt(); 101 } else if (typ == GType::Type::tString) { 102 g.SetString("KKK"); 103 printf("That's String. value(%s)\n", g.GetString().c_str()); 104 //value = g.GetString(); 105 } else { 106 printf("Unknow type(%d)\n", typ); 107 } 108 109 g.SetValue(value); 110 111 return 0; 112 } 113 114 template <typename T> 115 Result<T> GetValue(const std::string& key) 116 { 117 T val; 118 119 GetVal(key, val); 120 return Result<T>::GetResult(std::move(val)); 121 } 122 123 124 int main(int argc, char *argv[]) 125 { 126 printf("That's begin...\n"); 127 std::string key = "abc"; 128 129 printf("Get Int. Ret:%d\n", GetValue<int>(key).Value()); 130 printf("Get String. Ret:%s\n", GetValue<std::string>(key).Value().c_str()); 131 132 return (EXIT_SUCCESS); 133 }