c++任意變數型別獲取相關

三體問題發表於2019-06-13

    需要實現一個函式,template <class T> int get_unique_id(T t),傳入任意型別的變數,變數型別相同時,返回值id相同,且如果為不同的變數型別返回的id不同(例如 get_unique_id(100)  引數為int型別,返回值為  1,get_unique_id(1000) 引數同樣為int型別,返回值為 1, get_unique_id('A') 引數為char型別返回值為 2,get_unique_id('d')引數為char型別,返回值為 2...)。

   想法一:

    首先想到的實現方法:

    可以在模板函式get_unique_id()中定義一個static靜態變數 初值為static int i = -1; 在外邊定義一個全域性變數int g_cout = 0;

    利用模板函式編譯時,相同型別會使用同一個函式,不同型別會生成不同函式的機制進行生成(例如 get_unique_id(2) 和 get_unique_id(3) 都是整型,使用的是同一個函函式get_unique_id(int ),,而get_unique_id('C') 模板生成的函式是 get_unique_id(char)。考慮到每個函式裡都有一個static int i 變數,通過外部全域性變數的計數就能為每一個不同變數,返回

一個不同的id;程式碼實現如下:

int g_count = 0;
template<class T>
int get_unique_id(T t)
{
    static int unique_id = -1;

    if (unique_id  == -1) 
        unique_id  = g_count++;

    return unique_id ;
}

template<class T>
int get_unique_id()
{
    static int unique_id = -1;

    if (unique_id  == -1) 
        unique_id  = g_count++;

    return unique_id ;
}


int main()
{
	int i = 1, i1 = 3;
	char c = 'a', c1 = 'A';
	float f = 1.0, f1 = 2.5;
	double d = 2.5, d1 = 3.5;

	std::cout << get_unique_id(i) << get_unique_id(i1) << std::endl;
	std::cout << get_unique_id(c) << get_unique_id(c1) <<std::endl;
	std::cout << get_unique_id(f) << get_unique_id(f1) << std::endl;
	std::cout << get_unique_id(d) << get_unique_id(d1) << std::endl;

	std::cout << get_unique_id<int>() << get_unique_id<int>() << std::endl;
	std::cout << get_unique_id<char>() << get_unique_id<char>() <<std::endl;
	std::cout << get_unique_id<float>() << get_unique_id<float>() << std::endl;
	std::cout << get_unique_id<double>() << get_unique_id<double>() << std::endl;

	return 0;
}

輸出結果:

可以實現需求

想法二:

可以通過typeid關鍵字識別出不同型別,再經過map查詢,返回不同的id

實現如下:

std::map<std::string, int> g_type_name;
int g_count = 0;
template<class T>
int get_unique_id(T t)
{
	auto name = typeid(t).name();
	auto iter = g_type_name.find(name);

	if (iter == g_type_name.end())
	{
		int unique_id = g_count;
		g_type_name.insert(std::pair<std::string, int>(name, g_count++));
		return unique_id;
	}
	
	return iter->second;
}

template<class T>
int get_unique_id()
{
	auto name = typeid(T).name();
	auto iter = g_type_name.find(name);

	if (iter == g_type_name.end())
	{
		int unique_id = g_count;
		g_type_name.insert(std::pair<std::string, int>(name, g_count++));
		return unique_id;
	}
	
	return iter->second;
}



int main()
{
    int i = 1, i1 = 3;
	char c = 'a', c1 = 'A';
	float f = 1.0, f1 = 2.5;
	double d = 2.5, d1 = 3.5;

	std::cout << get_unique_id(i) << get_unique_id(i1) << std::endl;
	std::cout << get_unique_id(c) << get_unique_id(c1) <<std::endl;
	std::cout << get_unique_id(f) << get_unique_id(f1) << std::endl;
	std::cout << get_unique_id(d) << get_unique_id(d1) << std::endl;

	std::cout << get_unique_id<int>() << get_unique_id<int>() << std::endl;
	std::cout << get_unique_id<char>() << get_unique_id<char>() <<std::endl;
	std::cout << get_unique_id<float>() << get_unique_id<float>() << std::endl;
	std::cout << get_unique_id<double>() << get_unique_id<double>() << std::endl;
	return 0;
}

執行結果如下:

同樣也能實現上述功能。

感覺上第一種較簡單明瞭,不過會生成非常多static 全域性靜態變數,而且不具有可操作性,不能清空id(如果需要清空id,需要將所有型別的函式都執行一遍才能做到將每個函式中的static int unique置為-1),重新生成。

第二種想法,可以隨時釋放清空掉map中的內容,重新生成id序。

 

相關文章