C++中神奇的tuple詳解使用技巧及實(shí)例解析
一、tuple的基本概念
在C++中,tuple是一種數(shù)據(jù)結(jié)構(gòu),用于將多個(gè)值組合在一起,形成一個(gè)有序的元組。每個(gè)值在tuple中都有一個(gè)對應(yīng)的索引,可以通過索引來訪問和操作其中的值。
作用:
tuple將多個(gè)值組合在一起,形成一個(gè)整體。這些值可以是不同的數(shù)據(jù)類型,例如整數(shù)、浮點(diǎn)數(shù)、字符串等。
tuple中的值是有序排列的,每個(gè)值都有一個(gè)對應(yīng)的位置索引,可以通過索引來訪問和操作其中的值。
可以將tuple中的值解構(gòu)出來,分別賦值給不同的變量,方便對其中的值進(jìn)行單獨(dú)處理。
在函數(shù)中可以使用tuple作為返回類型,從而方便返回多個(gè)值,而不需要使用指針或引用參數(shù)。
C++17引入了結(jié)構(gòu)化綁定的特性,可以方便的從tuple中提取出其中的值并進(jìn)行使用,在代碼書寫上更加簡潔和可讀。
二、tuple基礎(chǔ)知識
C++中的tuple是一個(gè)標(biāo)準(zhǔn)庫類模板,用于存儲固定數(shù)量的異類對象。允許將多個(gè)對象捆綁成一個(gè)單一的對象,并且可以輕松地從中提取值或者通過結(jié)構(gòu)化綁定將其解構(gòu)到不同的變量中。tuple提供了一個(gè)通用的數(shù)據(jù)結(jié)構(gòu),可以保存不同類型的元素,并通過下標(biāo)或者std::get函數(shù)來訪問其中的值。
C++11引入了最初的tuple實(shí)現(xiàn), C++17進(jìn)一步擴(kuò)展了其功能,增加了結(jié)構(gòu)化綁定的支持,大大提高了tuple在實(shí)際應(yīng)用中的便利性。
2.1、tuple的創(chuàng)建和初始化
(1)直接初始化:
#include <tuple>
#include <string>
int main() {
// 直接初始化一個(gè)tuple
std::tuple<int, double, std::string> myTuple(10, 3.14, "Hello");
return 0;
}
(2)使用std::make_tuple函數(shù)進(jìn)行初始化:
#include <tuple>
#include <string>
int main() {
// 使用make_tuple函數(shù)創(chuàng)建一個(gè)tuple
auto myTuple = std::make_tuple(10, 3.14, "Hello");
return 0;
}
(3)使用std::tie進(jìn)行結(jié)構(gòu)化綁定的初始化:
#include <tuple>
#include <string>
int main() {
int a;
double b;
std::string c;
std::tie(a, b, c) = std::make_tuple(10, 3.14, "Hello");
return 0;
}
(4)使用std::forward_as_tuple進(jìn)行創(chuàng)建和初始化:
#include <tuple>
#include <string>
int main() {
auto myTuple = std::forward_as_tuple(10, 3.14, "Hello");
return 0;
}
2.2、tuple的成員訪問
(1)使用 std::get 函數(shù)按索引訪問元素:
#include <iostream>
#include <tuple>
int main() {
std::tuple<int, double, std::string> myTuple(10, 3.14, "Hello");
int intValue = std::get<0>(myTuple);
double doubleValue = std::get<1>(myTuple);
std::string stringValue = std::get<2>(myTuple);
std::cout << "Int value: " << intValue << std::endl;
std::cout << "Double value: " << doubleValue << std::endl;
std::cout << "String value: " << stringValue << std::endl;
return 0;
}
(2)使用 std::tie 進(jìn)行結(jié)構(gòu)化綁定,將 tuple 成員綁定到指定的變量:
#include <iostream>
#include <tuple>
int main() {
int a;
double b;
std::string c;
std::tuple<int, double, std::string> myTuple(10, 3.14, "Hello");
std::tie(a, b, c) = myTuple;
std::cout << "Int value: " << a << std::endl;
std::cout << "Double value: " << b << std::endl;
std::cout << "String value: " << c << std::endl;
return 0;
}
(3)使用結(jié)構(gòu)化綁定(C++17):
#include <iostream>
#include <tuple>
int main() {
std::tuple<int, double, std::string> myTuple(10, 3.14, "Hello");
auto [intValue, doubleValue, stringValue] = myTuple;
std::cout << "Int value: " << intValue << std::endl;
std::cout << "Double value: " << doubleValue << std::endl;
std::cout << "String value: " << stringValue << std::endl;
return 0;
}
注意,std::forward_as_tuple的初始化方式是無法使用結(jié)構(gòu)化綁定訪問元素的。
2.3、效果展示
示例:
#include <tuple>
#include <iostream>
# include <string>
int main(int n,char ** args)
{
// 直接初始化:
std::tuple<int, double, std::string> mtuple(1,2.0,"3a");
// 使用`std::make_tuple`函數(shù)進(jìn)行初始化:
auto mtuple2 = std::make_tuple(11,22.0,"3aa");
// 使用`std::tie`進(jìn)行結(jié)構(gòu)化綁定的初始化:
int a;
double b;
std::string s;
std::tie(a,b,s)=std::make_tuple(111,222.0,"3aaa");
// 使用`std::forward_as_tuple`進(jìn)行創(chuàng)建和初始化:
auto mtuple3=std::forward_as_tuple(1111,2222.0,"3aaaa");
// 使用 `std::get` 函數(shù)按索引訪問元素:
std::cout<<"使用 `std::get` 函數(shù)按索引訪問元素:"<<std::endl;
int oa=std::get<0>(mtuple);
double ob=std::get<1>(mtuple);
std::string os=std::get<2>(mtuple);
std::cout<<"oa="<<oa<<",ob="<<ob<<",os="<<os<<std::endl;
std::cout<<"使用 std::tie 進(jìn)行結(jié)構(gòu)化綁定,將 tuple 成員綁定到指定的變量:"<<std::endl;
std::cout<<"a="<<a<<",b="<<b<<",s="<<s<<std::endl;
std::cout<<"使用結(jié)構(gòu)化綁定(C++17):"<<std::endl;
// 注意,std::forward_as_tuple的初始化方式是無法使用結(jié)構(gòu)化綁定訪問元素的。
auto [intVal,doubleVal,strVal] = mtuple2;
std::cout<<"intVal="<<intVal<<",doubleVal="<<doubleVal<<",strVal="<<strVal<<std::endl;
return 0;
}
輸出:
使用 `std::get` 函數(shù)按索引訪問元素:
oa=1,ob=2,os=3a
使用 std::tie 進(jìn)行結(jié)構(gòu)化綁定,將 tuple 成員綁定到指定的變量:
a=111,b=222,s=3aaa
使用結(jié)構(gòu)化綁定(C++17):
intVal=11,doubleVal=22,strVal=3aa
2.4、tupe的成員函數(shù)、非成員函數(shù) 及 輔助類
| 成員函數(shù) | 描述 |
|---|---|
| constructor(C++11) | 構(gòu)造一個(gè)新的“元組”(公共成員函數(shù)) |
| operator=(C++11) | 將一個(gè)“元組”的內(nèi)容分配給另一個(gè)(公共成員函數(shù)) |
| swap (C++11) | 交換兩個(gè)元組的內(nèi)容(公共成員函數(shù)) |
| 非成員函數(shù) | 描述 |
|---|---|
| std::tuple_size | 返回 tuple 中元素的數(shù)量 |
| std::tuple_element | 返回 tuple 中指定索引的元素類型 |
| std::get | 通過索引訪問 tuple 的元素 |
| std::tie | 將 tuple 的元素綁定到指定的變量 |
| std::make_tuple | 創(chuàng)建 tuple |
| std::forward_as_tuple | 創(chuàng)建 tuple,保留變量的類型(包括引用) |
| std::tuple_cat | 連接兩個(gè)或多個(gè) tuple |
| std::swap | 交換兩個(gè) tuple 的內(nèi)容 |
| 輔助類 | 描述 |
|---|---|
| std::pair | 包含兩個(gè)值的不同類型的固定大小集合 |
| std::tuple_size | tuple 類型的長度 |
| std::tuple_element | tuple 類型的元素類型 |
這些成員函數(shù)、非成員函數(shù)和輔助類提供了豐富的功能,可以用于創(chuàng)建、訪問和操作 tuple,使得 tuple 在 C++ 中成為一個(gè)強(qiáng)大且靈活的數(shù)據(jù)結(jié)構(gòu)。
三、tuple高級應(yīng)用技巧
3.1、tuple的結(jié)構(gòu)化綁定
因?yàn)閠uple的結(jié)構(gòu)化綁定是一種非常方便的技巧,所以這里再次強(qiáng)調(diào)一下。在 C++17 中引入了結(jié)構(gòu)化綁定(structured bindings),可以用來將 tuple 或其他數(shù)據(jù)結(jié)構(gòu)中的元素綁定到多個(gè)變量中,而無需顯式地通過索引進(jìn)行訪問。這個(gè)技巧可以讓代碼更加清晰和易讀,特別是在處理多個(gè)返回值或者復(fù)雜的數(shù)據(jù)結(jié)構(gòu)時(shí)非常有用。
(1)對于 tuple 結(jié)構(gòu)化綁定的使用(再次強(qiáng)調(diào)):
std::tuple<int, double, std::string> myTuple(10, 3.14, "Hello"); auto [intValue, doubleValue, stringValue] = myTuple; std::cout << "Int value: " << intValue << std::endl; std::cout << "Double value: " << doubleValue << std::endl; std::cout << "String value: " << stringValue << std::endl;
(2)結(jié)構(gòu)化綁定也可以用于返回多個(gè)值的函數(shù):
std::tuple<int, double> getData() {
return std::make_tuple(10, 3.14);
}
auto [value1, value2] = getData();
std::cout << "Value 1: " << value1 << std::endl;
std::cout << "Value 2: " << value2 << std::endl;
(3)結(jié)構(gòu)化綁定還可以用于 STL 容器中的元素訪問:
std::map<int, std::string> myMap = {{1, "One"}, {2, "Two"}, {3, "Three"}};
for (const auto& [key, value] : myMap) {
std::cout << "Key: " << key << ", Value: " << value << std::endl;
}
(4)使用結(jié)構(gòu)化綁定處理復(fù)雜的數(shù)據(jù)結(jié)構(gòu):
std::unordered_map<std::string, std::pair<int, double>> data = {{"item1", {10, 3.14}}, {"item2", {20, 6.28}}};
for (const auto& [key, value] : data) {
int intValue = value.first;
double doubleValue = value.second;
std::cout << "Key: " << key << ", Int value: " << intValue << ", Double value: " << doubleValue << std::endl;
}
結(jié)構(gòu)化綁定的引入讓 tuple對其他數(shù)據(jù)結(jié)構(gòu)的處理變得更加簡潔、清晰和靈活。
3.2、tuple的運(yùn)算符重載
(1)比較運(yùn)算符重載(如==、!=、<、>等),實(shí)現(xiàn)自定義的比較行為。例如對 tuple 元素的比較:
bool operator==(const std::tuple<int, double>& t1, const std::tuple<int, double>& t2) {
return std::get<0>(t1) == std::get<0>(t2) && std::get<1>(t1) == std::get<1>(t2);
}
(2)算術(shù)運(yùn)算符重載如+、-、*、/等),實(shí)現(xiàn)對 tuple 的算術(shù)操作。例如對兩個(gè) tuple 進(jìn)行加法運(yùn)算:
std::tuple<int, double> operator+(const std::tuple<int, double>& t1, const std::tuple<int, double>& t2) {
return std::make_tuple(std::get<0>(t1) + std::get<0>(t2), std::get<1>(t1) + std::get<1>(t2));
}
(3)流操作符重載(<<和>>)。實(shí)現(xiàn)對 tuple 的輸入輸出操作,使得可以直接使用流操作符對 tuple 進(jìn)行輸入輸出:
template <typename... Args>
std::ostream& operator<<(std::ostream& os, const std::tuple<Args...>& t) {
os << "(";
std::apply([&os](const auto&... args) {
((os << args << ", "), ...);
}, t);
os << ")";
return os;
}
3.3、tuple的嵌套和組合
在 C++ tuple 嵌套和組合是為處理復(fù)雜的數(shù)據(jù)結(jié)構(gòu)提供了靈活性和便利性。
(1)嵌套 tuple:將多個(gè) tuple 組合成一個(gè)更大的 tuple,以便對多個(gè)數(shù)據(jù)結(jié)構(gòu)進(jìn)行整體操作,主要使用tuple_cat函數(shù)。
例如,將兩個(gè) tuple 進(jìn)行組合:
std::tuple<int, double> tuple1 = std::make_tuple(10, 3.14);
std::tuple<std::string, char> tuple2 = std::make_tuple("hello", 'A');
auto combinedTuple = std::tuple_cat(tuple1, tuple2);
// combinedTuple 的類型為 std::tuple<int, double, std::string, char>
(2)元組中嵌套元組:在 tuple 中嵌套另一個(gè) tuple,以實(shí)現(xiàn)更復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。例如,創(chuàng)建一個(gè)包含兩個(gè) tuple 的元組:
std::tuple<int, std::tuple<double, std::string>> nestedTuple = std::make_tuple(10, std::make_tuple(3.14, "hello"));
(3)使用結(jié)構(gòu)化綁定處理嵌套 tuple可以方便地處理嵌套的 tuple,通過一次性的聲明對嵌套 tuple 進(jìn)行解構(gòu)和賦值:
auto [intValue, nestedTupleValue] = nestedTuple; auto [doubleValue, stringValue] = nestedTupleValue;
(4)嵌套 tuple 的更復(fù)雜組合:多次的 tuple_cat 操作將多個(gè) tuple 進(jìn)行更復(fù)雜的組合,實(shí)現(xiàn)更為復(fù)雜的數(shù)據(jù)結(jié)構(gòu):
auto tuple1 = std::make_tuple(1, 2, 3); auto tuple2 = std::make_tuple(4, 5, 6); auto tuple3 = std::make_tuple(7, 8, 9); auto combinedTuple = std::tuple_cat(tuple1, tuple2, tuple3); // combinedTuple 的類型為 std::tuple<int, int, int, int, int, int, int, int, int>
特別是結(jié)合結(jié)構(gòu)化綁定的使用,可以簡化對嵌套和組合 tuple 的操作,提高代碼的可讀性和可維護(hù)性。
四、tuple實(shí)例解析
(1)實(shí)例一:使用tuple進(jìn)行函數(shù)返回多個(gè)值。
#include <iostream>
#include <tuple>
// 使用 std::make_tuple 返回多個(gè)值
std::tuple<int, double, float> calculateValues(int a, int b) {
int sum = a + b;
double difference = a - b;
float product = a * b;
float quotient = static_cast<float>(a) / b;
return std::make_tuple(sum, difference, product * quotient);
}
int main() {
int x = 10, y = 5;
// 使用 std::make_tuple 方式創(chuàng)建 tuple
auto result1 = calculateValues(x, y);
// 使用結(jié)構(gòu)化綁定和 std::tie 方式解構(gòu) tuple 結(jié)果
int s1, d1;
float pq1;
std::tie(s1, d1, pq1) = result1;
std::cout << "Sum: " << s1 << ", Difference: " << d1 << ", Product*Quotient: " << pq1 << std::endl;
// 使用直接通過 std::tuple 的構(gòu)造函數(shù)方式創(chuàng)建 tuple
std::tuple<int, double, float> result2(x + y, x - y, x * y / static_cast<float>(x));
int s2, d2;
float pq2;
std::tie(s2, d2, pq2) = result2;
std::cout << "Sum: " << s2 << ", Difference: " << d2 << ", Product*Quotient: " << pq2 << std::endl;
return 0;
}
函數(shù)接受兩個(gè)整數(shù)參數(shù),并返回了一個(gè)包含三個(gè)值的 tuple。在 main 函數(shù)中通過不同方式創(chuàng)建了 tuple 并使用結(jié)構(gòu)化綁定解構(gòu) tuple 中的值。
(2)實(shí)例二:使用tuple進(jìn)行數(shù)據(jù)結(jié)構(gòu)的擴(kuò)展。
#include <iostream>
#include <tuple>
int main() {
// 創(chuàng)建一個(gè)包含不同類型的元素的 tuple
std::tuple<int, double> data1 = std::make_tuple(10, 3.14);
// 定義結(jié)構(gòu)體
struct Person {
std::string name;
int age;
};
// 創(chuàng)建一個(gè)包含結(jié)構(gòu)體和其他類型的元素的 tuple
std::tuple<Person, std::string, int> data2 = std::make_tuple(Person{"Alice", 30}, "Hello", 99);
// 創(chuàng)建一個(gè)包含 tuple 的 tuple
std::tuple<int, std::tuple<double, std::string>> data3 = std::make_tuple(5, std::make_tuple(3.14, "pi"));
// 創(chuàng)建一個(gè)更復(fù)雜的嵌套結(jié)構(gòu)
std::tuple<std::string, std::tuple<int, double>, std::tuple<float, char>> data4 = std::make_tuple("Nested", std::make_tuple(10, 3.14), std::make_tuple(4.5f, 'A'));
// 訪問和打印 tuple 中的元素
std::cout << "Data 1: " << std::get<0>(data1) << ", " << std::get<1>(data1) << std::endl;
std::cout << "Data 2: " << std::get<0>(std::get<0>(data2)).name << ", " << std::get<0>(std::get<0>(data2)).age << ", " << std::get<1>(data2) << ", " << std::get<2>(data2) << std::endl;
std::cout << "Data 3: " << std::get<0>(data3) << ", " << std::get<0>(std::get<1>(data3)) << ", " << std::get<1>(std::get<1>(data3)) << std::endl;
std::cout << "Data 4: " << std::get<0>(data4) << ", " << std::get<0>(std::get<1>(data4)) << ", " << std::get<1>(std::get<1>(data4)) << ", " << std::get<0>(std::get<2>(data4)) << ", " << std::get<1>(std::get<2>(data4)) << std::endl;
return 0;
}
示例中創(chuàng)建了多個(gè)不同的 tuple 數(shù)據(jù)結(jié)構(gòu),每個(gè)都展示了一種常見的嵌套和組合方式。
(3)實(shí)例三:作為STL容器類的元素類型。例如 vector 和 map,使用 tuple 來存儲不同類型的元素:
#include <iostream>
#include <vector>
#include <map>
#include <tuple>
int main() {
// 使用 tuple 作為 vector 的元素類型
std::vector<std::tuple<int, double, std::string>> vec;
// 添加元素到 vector
vec.push_back(std::make_tuple(10, 3.14, "Hello"));
vec.push_back(std::make_tuple(20, 6.28, "World"));
// 遍歷 vector 中的元組
for (const auto& item : vec) {
std::cout << "Int value: " << std::get<0>(item) << std::endl;
std::cout << "Double value: " << std::get<1>(item) << std::endl;
std::cout << "String value: " << std::get<2>(item) << std::endl;
}
// 使用 tuple 作為 map 的 value 類型
std::map<int, std::tuple<std::string, double>> myMap;
// 添加元素到 map
myMap[1] = std::make_tuple("John", 175.5);
myMap[2] = std::make_tuple("Alice", 160.3);
// 遍歷 map 中的元組
for (const auto& pair : myMap) {
std::cout << "Key: " << pair.first << std::endl;
std::cout << "Name: " << std::get<0>(pair.second) << std::endl;
std::cout << "Height: " << std::get<1>(pair.second) << std::endl;
}
return 0;
}
五、tuple的性能和適用場景分析
tuple的性能:
(1)與自定義結(jié)構(gòu)體的性能比較:tuple不一定總是比自定義結(jié)構(gòu)體優(yōu)秀,tuple 也可能比使用自定義結(jié)構(gòu)體更加低效,因?yàn)?tuple 通常需要進(jìn)行運(yùn)行時(shí)的動態(tài)內(nèi)存分配。而使用自定義結(jié)構(gòu)體會更加高效,因?yàn)樗膬?nèi)存布局更為緊湊,沒有額外的開銷。
(2)當(dāng)tuple中包含的元素?cái)?shù)量較少時(shí),tuple 的性能通常是可以接受的,并且不會造成太大的性能損耗。
(3)當(dāng)tuple中包含大量的元素時(shí),tuple 的性能可能會受到影響,特別是在元組的創(chuàng)建、銷毀和訪問操作方面。
建議:如果對性能有較高要求,使用結(jié)構(gòu)體或類來代替 tuple,因?yàn)榻Y(jié)構(gòu)體或類通常會在編譯時(shí)進(jìn)行優(yōu)化,并且在內(nèi)存布局方面更加緊湊。
tuple的適用場景:
(1)返回多個(gè)值:當(dāng)需要從函數(shù)中返回多個(gè)值時(shí),使用 tuple 是一種方便的方式。
(2)想將多個(gè)數(shù)據(jù)項(xiàng)打包在一起,并且數(shù)據(jù)項(xiàng)的類型各不相同 時(shí)使用 tuple 可以很好地解決這個(gè)問題,避免創(chuàng)建新的自定義結(jié)構(gòu)體。
(3)函數(shù)參數(shù)傳遞:函數(shù)需要接受多個(gè)不同類型的參數(shù)時(shí),使用 tuple 可以很方便地將這些參數(shù)打包在一起,并傳遞給函數(shù)。
(4)中間結(jié)果存儲:在一些算法或計(jì)算過程中會產(chǎn)生中間結(jié)果,使用 tuple 可以方便地將這些中間結(jié)果存儲起來,以便之后使用。
(5)與算法庫結(jié)合:在使用標(biāo)準(zhǔn)庫中的算法時(shí),tuple 也有其用武之地,比如可以方便地將多個(gè)數(shù)據(jù)項(xiàng)打包在一起,用作算法的輸入或輸出;或者遍歷容器時(shí)使用tuple結(jié)構(gòu)化綁定。
tuple與其他數(shù)據(jù)結(jié)構(gòu)的對比:
(1)Array(數(shù)組):數(shù)組是一種包含相同類型元素的數(shù)據(jù)結(jié)構(gòu),而 tuple 允許存儲不同類型的元素。因此,如果要存儲相同類型的元素,選擇使用數(shù)組;而如果要存儲不同類型的元素,使用 tuple。
(2)Pair(對):pair 是一種特殊的 tuple,它只能存儲兩個(gè)元素。因此,如果只需要存儲兩個(gè)元素,使用 pair;要存儲三個(gè)及以上的元素,使用 tuple。
(3)Struct(結(jié)構(gòu)體):結(jié)構(gòu)體是一種自定義的數(shù)據(jù)結(jié)構(gòu),可以包含不同類型的數(shù)據(jù)成員,并且可以定義自己的成員函數(shù)。相比之下,tuple 是一個(gè)泛化的數(shù)據(jù)結(jié)構(gòu),通常用于臨時(shí)存儲一些松散相關(guān)的數(shù)據(jù),而不需要為每個(gè)元素定義一個(gè)具體的名稱。
(4)Vector(向量):vector 是一種動態(tài)數(shù)組,用于存儲相同類型的元素。提供了動態(tài)擴(kuò)展和訪問元素的能力。tuple 則更適合用于存儲固定數(shù)量的松散相關(guān)的數(shù)據(jù),不要求動態(tài)操作。
總結(jié)
tuple 具有多種強(qiáng)大功能和靈活應(yīng)用:
- 存儲多個(gè)不同類型的值,便于打包和傳遞多元數(shù)據(jù)。
- 在函數(shù)中方便地返回多個(gè)值,簡化了函數(shù)返回值的處理。
- 可以作為函數(shù)的參數(shù)類型,簡化了參數(shù)列表的處理。
- 可以用于元編程和函數(shù)式編程范式,用于表示元組、模式匹配等。
- 與標(biāo)準(zhǔn)庫中的算法結(jié)合使用,方便地作為算法的輸入或輸出。
- 可以用于解耦數(shù)據(jù),不需要?jiǎng)?chuàng)建新的自定義數(shù)據(jù)結(jié)構(gòu)。
- 使代碼更簡潔、更易讀、更靈活。
到此這篇關(guān)于C++中神奇的tuple詳解使用技巧及實(shí)例解析的文章就介紹到這了,更多相關(guān)C++ tuple使用技巧和實(shí)例內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
舉例講解C語言的fork()函數(shù)創(chuàng)建子進(jìn)程的用法
fork函數(shù)是Linux下一個(gè)近乎專有的C語言函數(shù),因?yàn)槭褂脮r(shí)需要調(diào)用unistd.h這個(gè)頭文件,這里我們就在Linux環(huán)境下舉例講解C語言的fork()函數(shù)創(chuàng)建子進(jìn)程的用法,需要的朋友可以參考下2016-06-06
Qt實(shí)現(xiàn)網(wǎng)絡(luò)聊天室的示例代碼
本文主要介紹了Qt實(shí)現(xiàn)網(wǎng)絡(luò)聊天室,實(shí)現(xiàn)一個(gè)在線聊天室, 使用tcp對客戶端和服務(wù)器端進(jìn)行通訊。具有一定的參考價(jià)值,具有一定的參考價(jià)值,2021-06-06
notepad介紹及插件cmake編譯過程(替代notepad++)
這篇文章主要介紹了notepad介紹及插件cmake編譯過程(替代notepad++),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-03-03

