網站首頁 編程語言 正文
一、說明
Boost.Utility 庫是雜項、有用的類和函數的集合,它們太小而無法在獨立庫中維護。雖然實用程序很小并且可以快速學習,但它們完全無關。與其他章節中的示例不同,此處的代碼示例不是相互構建的,因為它們是獨立的實用程序。
雖然大多數實用程序都在 boost/utility.hpp 中定義,但有些實用程序有自己的頭文件。以下示例包括所介紹的實用程序的相應頭文件。
二、Boost.Utility庫示例和代碼
示例 69.1。使用 boost::checked_delete()
#include <boost/checked_delete.hpp>
#include <boost/intrusive/list.hpp>
#include <string>
#include <utility>
#include <iostream>
struct animal : public boost::intrusive::list_base_hook<>
{
std::string name_;
int legs_;
animal(std::string name, int legs) : name_{std::move(name)},
legs_{legs} {}
};
int main()
{
animal *a = new animal{"cat", 4};
typedef boost::intrusive::list<animal> animal_list;
animal_list al;
al.push_back(*a);
al.pop_back_and_dispose(boost::checked_delete<animal>);
std::cout << al.size() << '\n';
}
Example?69.1
示例 69.1 將函數 boost::checked_delete() 作為參數傳遞給成員函數 pop_back_and_dispose(),該函數由 Boost.Intrusive 的類 boost::intrusive::list 提供。 boost::intrusive::list 和 pop_back_and_dispose() 在第 18 章中介紹,而 boost::checked_delete() 由 Boost.Utility 提供并在 boost/checked_delete.hpp 中定義。
boost::checked_delete() 期望作為其唯一參數的指針指向將被 delete 刪除的對象。因為 pop_back_and_dispose() 需要一個函數來銷毀相應的對象,所以傳入 boost::checked_delete() 是有意義的——這樣,您就不需要定義類似的函數。
與 delete 不同,boost::checked_delete() 確保要銷毀的對象的類型是完整的。 delete 將接受指向具有不完整類型的對象的指針。雖然這涉及您通常可以忽略的 C++ 標準細節,但您應該注意 boost::checked_delete() 與調用 delete 并不完全相同,因為它對其參數提出了更高的要求。
Boost.Utility 還提供了 boost::checked_array_delete(),可用于銷毀數組。它調用 delete[] 而不是 delete。
此外,boost::checked_deleter 和 boost::checked_array_deleter 這兩個類可用于創建行為分別類似于 boost::checked_delete() 和 boost::checked_array_delete() 的函數對象。
示例 69.2。使用 BOOST_CURRENT_FUNCTION
#include <boost/current_function.hpp>
#include <iostream>
int main()
{
const char *funcname = BOOST_CURRENT_FUNCTION;
std::cout << funcname << '\n';
}
Example?69.2
示例 69.2 使用在 boost/current_function.hpp 中定義的宏 BOOST_CURRENT_FUNCTION 將周圍函數的名稱作為字符串返回。
BOOST_CURRENT_FUNCTION 提供了一種獨立于平臺的方法來檢索函數的名稱。從 C++11 開始,您可以使用標準化宏 __func__ 做同樣的事情。在 C++11 之前,Visual C++ 和 GCC 等編譯器支持宏 __FUNCTION__ 作為擴展。 BOOST_CURRENT_FUNCTION 使用編譯器支持的任何宏。
如果使用 Visual C++ 2013 編譯,示例 69.2 顯示 int __cdecl main(void)。
示例 69.3。使用 boost::prior() 和 boost::next()
#include <boost/next_prior.hpp>
#include <array>
#include <algorithm>
#include <iostream>
int main()
{
std::array<char, 4> a{{'a', 'c', 'b', 'd'}};
auto it = std::find(a.begin(), a.end(), 'b');
auto prior = boost::prior(it, 2);
auto next = boost::next(it);
std::cout << *prior << '\n';
std::cout << *it << '\n';
std::cout << *next << '\n';
}
Boost.Utility 提供了兩個函數,boost::prior() 和 boost::next(),它們返回一個相對于另一個迭代器的迭代器。在示例 69.3 中,它指向數組中的“b”,prior 指向“a”,然后指向“d”。
與 std::advance() 不同,boost::prior() 和 boost::next() 返回一個新的迭代器并且不修改傳入的迭代器。
除了迭代器之外,這兩個函數都接受第二個參數,該參數指示向前或向后移動的步數。在示例 69.3 中,迭代器在對 boost::prior() 的調用中向后移動了兩步,在對 boost::next() 的調用中向前移動了一步。
步數始終為正數,即使對于向后移動的 boost::prior() 也是如此。
要使用 boost::prior() 和 boost::next(),請包含頭文件 boost/next_prior.hpp。
這兩個函數都被添加到 C++11 的標準庫中,它們被稱為 std::prev() 和 std::next()。它們在頭文件迭代器中定義。
示例 69.4。使用 boost::noncopyable
#include <boost/noncopyable.hpp>
#include <string>
#include <utility>
#include <iostream>
struct animal : boost::noncopyable
{
std::string name;
int legs;
animal(std::string n, int l) : name{std::move(n)}, legs{l} {}
};
void print(const animal &a)
{
std::cout << a.name << '\n';
std::cout << a.legs << '\n';
}
int main()
{
animal a{"cat", 4};
print(a);
}
Boost.Utility 提供類 boost::noncopyable,它在 boost/noncopyable.hpp 中定義。此類使復制(和移動)對象變得不可能。
通過將復制構造函數和賦值運算符定義為私有成員函數,或者從 C++11 開始,通過使用 delete 刪除復制構造函數和賦值運算符,可以達到相同的效果。然而,從 boost::noncopyable 派生明確說明類的對象應該是不可復制的。
注意:
一些開發人員更喜歡 boost::noncopyable,而其他開發人員更喜歡使用 delete 顯式刪除成員函數。您會在 Stack Overflow 等地方找到這兩種方法的論點。
可以編譯和執行示例 69.4。但是,如果將 print() 函數的簽名修改為按值而不是按引用獲取動物類型的對象,則生成的代碼將不再編譯。
示例 69.5。使用 boost::addressof()
#include <boost/utility/addressof.hpp>
#include <string>
#include <iostream>
struct animal
{
std::string name;
int legs;
int operator&() const { return legs; }
};
int main()
{
animal a{"cat", 4};
std::cout << &a << '\n';
std::cout << boost::addressof(a) << '\n';
}
為了檢索特定對象的地址,即使運算符 & 已被重載,Boost.Utility 提供了函數 boost::addressof(),它在 boost/utility/addressof.hpp 中定義(參見示例 69.5)。在 C++11 中,此函數成為標準庫的一部分,并在頭文件內存中作為 std::addressof() 提供。
示例 69.6。使用 BOOST_BINARY
#include <boost/utility/binary.hpp>
#include <iostream>
int main()
{
int i = BOOST_BINARY(1001 0001);
std::cout << i << '\n';
short s = BOOST_BINARY(1000 0000 0000 0000);
std::cout << s << '\n';
}
宏 BOOST_BINARY 允許您創建二進制形式的數字。標準 C++ 僅支持十六進制和八進制形式,使用前綴 0x 和 0。C++11 引入了用戶定義文字,允許您定義自定義后綴,但在 C+ 中仍然沒有以二進制形式使用數字的標準方法+11。
示例 69.6 顯示 145 和 -32768。 s 中存儲的位序列表示一個負數,因為 16 位類型的 short 使用第 16 位——short 中的最高有效位——作為符號位。
BOOST_BINARY 只是提供了另一種寫數字的選項。因為在 C++ 中,數字的默認類型是 int,所以 BOOST_BINARY 也使用 int。要定義一個 long 類型的數字,請使用宏 BOOST_BINARY_L,它生成等同于以字母 L 為后綴的數字。
Boost.Utility 包括額外的宏,例如 BOOST_BINARY_U,它初始化一個沒有符號位的變量。所有這些宏都在頭文件 boost/utility/binary.hpp 中定義。
示例 69.7。使用 boost::string_ref
#include <boost/utility/string_ref.hpp>
#include <iostream>
boost::string_ref start_at_boost(boost::string_ref s)
{
auto idx = s.find("Boost");
return (idx != boost::string_ref::npos) ? s.substr(idx) : "";
}
int main()
{
boost::string_ref s = "The Boost C++ Libraries";
std::cout << start_at_boost(s) << '\n';
}
Example?69.7
示例 69.7 引入了類 boost::string_ref,它是對僅支持讀取訪問的字符串的引用。在某種程度上,該引用可與 const std::string& 相媲美。然而,const std::string& 要求存在一個 std::string 類型的對象。 boost::string_ref 也可以在沒有 std::string 的情況下使用。 boost::string_ref 的好處是,與 std::string 不同,它不需要分配內存。
示例 69.7 在字符串中查找單詞“Boost”。如果找到,將顯示以該詞開頭的字符串。如果未找到“Boost”一詞,則會顯示一個空字符串。 main() 中字符串 s 的類型不是 std::string,而是 boost::string_ref。因此,沒有內存分配給 new,也沒有創建副本。 s 直接指向文字字符串“The Boost C++ Libraries”。
start_at_boost() 的返回值類型是 boost::string_ref,而不是 std::string。該函數不返回新字符串,它返回一個引用。此引用指向參數的子字符串或空字符串。 start_at_boost() 要求原始字符串在使用 boost::string_ref 類型的引用時保持有效。如果可以保證這一點,如示例 69.7 所示,則可以避免內存分配。
還可以使用其他實用程序,但它們超出了本書的范圍,因為它們主要由 Boost 庫的開發人員使用或用于模板元編程。 Boost.Utility 的文檔提供了這些附加實用程序的相當全面的概述,如果您有興趣,可以作為起點。
原文鏈接:https://yamagota.blog.csdn.net/article/details/128205736
相關推薦
- 2022-03-19 C語言常量介紹_C 語言
- 2022-12-03 Golang檢查變量類型的四種方式_Golang
- 2022-10-03 react實現數據監聽方式_React
- 2022-08-29 使用C#中的Flags特性_C#教程
- 2022-06-21 Android實現登陸界面的記住密碼功能_Android
- 2022-09-26 Redis?哈希Hash底層數據結構詳解_Redis
- 2023-04-17 Python屬性私有化詳解_python
- 2022-12-29 React點擊事件的兩種寫法小結_React
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支