1. 程式人生 > >STD::MAP與結構體的互轉

STD::MAP與結構體的互轉

問題描述大概如下,一個已經存在的庫a.lib,和伺服器通訊,全是通過結構體,或者基本資料型別進行的,現在額另外一個框架f,提供了c++和js交 互的方法,但只支援基本資料型別,std 容器,js裡面的物件被對映成std::map<string,string>供c++層訪問,現在需要通過JS呼叫a.lib的介面,所以 自然想到的是,做一箇中間層,把map轉換成struct,還好,a.lib要求的結構體非常簡單,所有成員只包括基本資料型別,或者char 陣列,並且,不含內嵌結構體

由於已經有了boost::to_string,所以還要寫一個from_string的輔助函式,程式碼如下:

//1.
template <typename T>
struct FromString {
	static const char* type() { return "Generic"; }
	static void from_string(T& dest, const std::string& source)
	{
		try
		{
			dest = boost::lexical_cast<T>(source);
		}
		catch (boost::bad_lexical_cast& e)
		{
			std::cerr << "bad_lexical_cast:"<<e.what() << std::endl;
			memcpy(&dest, source.c_str(), std::min<std::size_t>(sizeof(dest), source.size()));
		}
	}
};

//2.
template <>
struct FromString < char* > {
	static const char* type() { return "char*"; }
	static void from_string(char* dest, const std::string& source)
	{
		memset(dest, 0, sizeof(dest));
		memcpy(dest, source.data(), source.size());
	}
};
//3.
template< std::size_t N >
struct FromString < char[N] > {
	static const char* type() { return "char[N]"; }
	static void from_string(char dest[N], const std::string& source)
	{
		memset(dest, 0, sizeof(dest));
		memcpy(dest, source.data(), source.size());
	}
};
template<>
struct FromString < char[10] > {
	static const char* type() { return "char[10]"; }
	static void from_string(char dest[10], const std::string& source)
	{
		memset(dest, 0, sizeof(dest));
		memcpy(dest, source.data(), source.size());
	}
};
//4.
template <>
struct FromString < char[] > {
	static const char* type() { return "char[]"; }
	static void from_string(char dest[], const std::string& source)
	{
		memset(dest, 0, sizeof(dest));
		memcpy(dest, source.data(), source.size());
	}
};

template <typename T>
void from_string(T& expected, const std::string& str_value) {
	std::cerr << expected << " type " << FromString<T>::type();
	FromString<T>::from_string(expected, str_value);
	std::cerr << expected << std::endl;
}

然後是要將map通過key,找到結構體的對應名稱的欄位,然後把這個值付給它,這裡用了boost.pp

只要上面的思路搞清楚了,將結構體的每個欄位填充到map裡面就相當清晰了

#define DEF_MEMBER2( r, data, elem ) std::string BOOST_PP_CAT(key_,elem) = BOOST_PP_STRINGIZE(elem); \
std::string BOOST_PP_CAT(val_,elem) = boost::to_string(data->elem);
#define DEF_ASSIGN2( r, data, elem ) data[BOOST_PP_CAT(key_,elem)] = BOOST_PP_CAT(val_,elem);
#define MEMBERS2MAP(st,map_data, members )         \
do{                                          \
if(!st) break;                               \
BOOST_PP_SEQ_FOR_EACH( DEF_MEMBER2 ,st, members )\
BOOST_PP_SEQ_FOR_EACH( DEF_ASSIGN2,map_data, members )\
}while(0)
下面是如何使用:注意map轉換成結構體之前,必須要清0,否則將有可能導致模板匹配不正確
struct test_st
{
	
	int a;
	int b;
	int c;
	float d;
	char e[32];
	char f;
};
int main(int argc, char *argv[])
{
test_st st1;
memset(&st1, 0, sizeof(st1));
std::map<std::string, std::string> containe;
boost::assign::insert(containe)("a", "1")("b", "2")("c", "3")("d", "4.2")("e", "aabc")("f","x");
MAP2MEMBERS(&st1, containe, (a)(b)(c)(d)(e)(f));
std::cout << "st1.a=" << st1.a << std::endl
<< "st1.b=" << st1.b << endl
<< "st1.c=" << st1.c << endl
<< "st1.d=" << st1.d << endl
<< "st1.e=" << st1.e << endl
<< "st1.f=" << st1.f << endl;
return 0;
}
最後還要針對這個框架,為bool值再做一個特化版本,以下字元被認為是true:”1″, “t”, “true”, “yes”, or “y”,其他的都是false
template <>
struct FromString<bool> {
	static const char* type() { return "Boolean"; }
	static void from_string(bool& dest, const std::string& source)
	{
		try
		{
			static string  true_strs[] = { "1","t","true","yes","y" };
			if (std::find(true_strs, true_strs + 5, source) != (true_strs + 5))
			{
				dest = true;
			}
			else
			{
				dest = false;
			}
		}
		catch (boost::bad_lexical_cast& e)
		{
			std::cerr << "bad_lexical_cast:" << e.what() << std::endl;
			memcpy(&dest, source.c_str(), std::min<std::size_t>(sizeof(dest), source.size()));
		}
	}
};




相關推薦

STD::MAP結構

問題描述大概如下,一個已經存在的庫a.lib,和伺服器通訊,全是通過結構體,或者基本資料型別進行的,現在額另外一個框架f,提供了c++和js交 互的方法,但只支援基本資料型別,std 容器,js裡面的物件被對映成std::map<string,string>供c

jsonC++結構

程式碼在 https://github.com/xyz347/x2struct 可以將 json轉換為C++結構體,也可以將C++結構體轉為json字串。 除了json,同時還支援 xml/bson/libconfig與C++結構體之間的互轉(預設關閉,如果需要請修改co

map結構結合使用

在編寫map中新增結構體的時候,嘗試了好多種的方法,網上的這種方法給我提供了一個新奇的思路,在此記錄下。 #include <iostream> #include <map> using namespace std; typedef st

Go語言基礎(十四)—— Go語言切片,map結構Json的序列化,反序列化

序列化和反序列化 序列化概念理解:就是將變數從記憶體中變成可儲存或傳輸的過程稱之為序列化,序列化之後,就可以把序列化後的內容寫入磁碟,或者通過網路傳輸到別的機器上。 反序列化則就是序列化反過來,把變數內容從序列化的物件重新讀到記憶體裡稱之為反序列化 序列化結構體案例: packa

addrinfo結構原型-(自 cxz2009)

info 字符 logs 常用 設置 toc 返回 type ive addrinfo結構體原型 typedef struct addrinfo { int ai_flags; //AI_PASSIVE,AI_CANONNAME,AI_NUMERICHO

Java中net.sf.json包關於JSON對象的坑

一句話 declared bean == float 谷歌 數據類型 運行時 定制   在Web開發過程中離不開數據的交互,這就需要規定交互數據的相關格式,以便數據在客戶端與服務器之間進行傳遞。數據的格式通常有2種:1、xml;2、JSON。通常來說都是使用JSON來傳遞數

集合數組

代碼 ons ace 表示 但是 漢字 運用 修改 style   一.集合轉數組   以ArrayList集合為例,使用該集合的一個成員方法toArray(),可以將一個集合對象轉化為一個數組。如下所示:   1 void listToArray(){ 2

java 字符ASCII碼

方法 style println span har pos system pan blog 字符轉對應ASCII碼 // 方法一:將char強制轉換為byte char ch = ‘A‘; byte byteAscii = (byte) ch; System.out.

縱表橫表實例

sum 代碼 sql help blog 所有 .cn light div 1.縱表轉橫表: 縱表結構:Table1 轉換後的橫表結構: Sql示例代碼: ? 1 2 3 4 5 6 7 8 9 10 11 select username, sum

gensimnumpy array

字母轉 IT aid coo tool rdo ont array dense 目的 將gensim輸出的格式轉化為numpy array格式,支持作為scikit-learn,tensorflow的輸入 實施 使用nltk庫的停用詞和網上收集的資料整合成一份新的停用詞

SQL縱表橫表

padding else 結束 esc ase when sum -a order 1.縱表轉橫表: 縱表結構:Table1 轉換後的橫表結構: Sql示例代碼: select username, sum(case Course when ‘語文‘ t

JDK1.8 LocalDateTime 時間類字符

nth formatter ear class light 大小寫 orm ava 1.8 public static void main(String[] args) { DateTimeFormatter dateTimeFormatter=Date

javascriptphp時/分/秒秒數

cond log pre UNC ole arr 時間 min seconds javascript: /* 時間轉換成秒 */ function time_to_second(time){ var arr = time.split(‘:‘) var hour = arr[

CAD小技巧-怎麽將DWGDXF進行

ima dde 電腦 菜單欄 轉換 希望 拖拽 -o 朋友 CAD小技巧,怎麽將DWG與DXF進行互轉?在CAD行業中小夥伴們都知道,他們每天的日常工作就是編輯CAD圖紙文件,以前的CAD前輩們都是用手繪制的,但是隨著科技的發展,現在編輯CAD圖紙一般都是借助CAD編輯器來

IOS中的NSStringNSArray的

將string字串轉換為array陣列  NSArray  *array = [Str componentsSeparatedByString:@","];//分隔符逗號 將array陣列轉換為string字串 &n

js字元ASCII碼的方法

大寫字母A-Z對應的ASCII碼值是65-90 小寫字母a-z對應的ASCII碼值是97-122 將字母轉為ascii嘛的方法: var str = "A"; str.charCodeAt(); // 65 var str1 = 'a'; str1.charCodeAt()

c語言typedef 結構指標

轉載部落格:https://blog.csdn.net/developerof/article/details/24885205?utm_source=blogxgwz0  #include<stdio.h> #include<

xstream--xml工具類--java物件轉換JSONObject、xmljava物件

工作環境: myeclipse2013、jdk1.8、fastjson1.1.41、xstream1.4.3 import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.Writer;

影象RGB2YUVYUV2RGB格式介紹

1 YUV格式與RGB格式說明   由於不同國家的電視訊號系統支援的影象格式不同,有YUV格式成像,也有RGB格式成像,因此為了保證相容性,需要進行RGB與YUV格式的互轉。 另外YUV格式具有亮度資訊和色彩資訊分離的特點,但大多數影象處理操作都是基於RGB格式,需要將RGB格式轉

CAD小技巧-怎麼將DWGDXF進行

CAD小技巧,怎麼將DWG與DXF進行互轉?在CAD行業中小夥伴們都知道,他們每天的日常工作就是編輯CAD圖紙檔案,以前的CAD前輩們都是用手繪製的,但是隨著科技的發展,現在編輯CAD圖紙一般都是藉助CAD編輯器來進行繪製,既方便又快捷,但是編輯出來的CAD圖紙都是dwg格式的,這樣不利用我們進行檢視,那怎麼