C++中std::is_object的具體使用
1.概述
std::is_object是一種C++類型特性,其用途是判斷一個(gè)類型是否是一個(gè)對(duì)象類型(除了函數(shù)、引用和void類型)。如下例子:
#include <iostream>
#include <type_traits>
class A {};
int main() {
std::cout << std::boolalpha;
std::cout << "is_object:" << std::endl;
std::cout << "int: " << std::is_object<int>::value << std::endl; //輸出:true
std::cout << "A: " << std::is_object<A>::value << std::endl; //輸出:true
std::cout << "A&: " << std::is_object<A&>::value << std::endl; //輸出:false
std::cout << "A*: " << std::is_object<A*>::value << std::endl; //輸出:true
std::cout << "int(int): " << std::is_object<int(int)>::value << std::endl; //輸出:false
std::cout << "int(*)(int): " << std::is_object<int(*)(int)>::value << std::endl; //輸出:
// true
return 0;
}2.原理分析
2.1.std::is_object
std::is_object的源碼如下:
template <class _Ty>
constexpr bool is_object_v = !is_function_V<_Ty> && !is_reference_v<_Ty> && !is_void_v<_Ty>;
template <class _Ty>
struct is_object : bool_constant<is_object_v<_Ty>> {};
is_function_v<T> : 判斷是否檢查 T 是否為函數(shù)類型。如 std::function 、 lambda 、有重載 operator() 的類和指向函數(shù)指針不是函數(shù)類型。若 T 為函數(shù)類型,則提供等于 true 的成員常量 value 。否則, value 等于 false, 示例如下:
#include <type_traits>
using namespace std;
struct GeeksforGeeks {
int func() const&;
};
template <typename>
struct Computer {
};
template <class A, class B>
struct Computer<B A::*> {
using member_type = B;
};
int x1();
int main()
{
cout << is_function<int(int)>::value << endl; //輸出:true
cout << is_function<GeeksforGeeks>::value << endl; //輸出:false
cout << is_function<int>::value << endl; //輸出:false
cout << is_function<decltype(x1)>::value << endl; //輸出:true
using A = Computer<decltype(
&GeeksforGeeks::func)>::member_type;
cout << is_function<A>::value << endl; //輸出:true
return 0;
}is_reference_v<T> : 若 T 是引用類型(左值引用或右值引用),則提供等于 true 的成員常量 value 。對(duì)于任何其他類型, value 為 false; 示例如下:
#include <iostream>
#include <type_traits>
using namespace std;
class MyTest {
};
int main() {
cout << "\n class TP : "<<is_reference<MyTest>::value; //輸出:false
cout << "\n class TP&: "<<is_reference<MyTest&>::value; //輸出:true
cout << "\n class TP&&: "<<is_reference<MyTest&&>::value; //輸出:true
return 0;
}is_void_v<T> : ?檢查 T 是否為 void 類型。若 T 是類型 void 、 const void 、 volatile void 或 const volatile void ,則提供等于 true 的成員常量 value。否則, value 等于 false; 示例如下:
#include <iostream>
#include <type_traits>
int main()
{
std::cout << std::boolalpha;
std::cout << std::is_void<void>::value << '\n'; //輸出:true
std::cout << std::is_void<int>::value << '\n'; //輸出:false
}2.2.bool_constant
bool_constant是integral_constant<bool, _Val>的別名,從下面的定義可以看出:
template <bool _Val> using bool_constant = integral_constant<bool, _Val>; using true_type = bool_constant<true>; using false_type = bool_constant<false>;
那么integral_constant的定義呢?繼續(xù)看下面:
template <class _Ty, _Ty _Val>
struct integral_constant {
static constexpr _Ty value = _Val;
using value_type = _Ty;
using type = integral_constant;
constexpr operator value_type() const noexcept {
return value;
}
_NODISCARD constexpr value_type operator()() const noexcept {
return value;
}
};std::integral_constant包裝特定類型的靜態(tài)常量,它是C++類型特征的基類。我們可以看到,這個(gè)模板類接受兩個(gè)參數(shù),一個(gè)類型_Ty和一個(gè)該類型的值_Val。它提供了一個(gè)靜態(tài)的常量成員value,該成員的值就是傳入的_Val;其中,using value_type = _Ty;和using type = integral_constant;分別用來(lái)定義value的類型以及integral_constant本身的類型。
然后,它還提供了兩個(gè)轉(zhuǎn)換函數(shù),一個(gè)是constexpr operator value_type() const noexcept,可以將std::integral_constant對(duì)象隱式轉(zhuǎn)換為T(mén)類型的值;另一個(gè)是constexpr value_type operator()() const noexcept,可以將std::integral_constant對(duì)象當(dāng)作函數(shù)來(lái)調(diào)用,并返回其內(nèi)部保存的常量。
std::integral_constant 的兩個(gè)最常用的特化版本是 std::true_type 和 std::false_type。它們是 std::integral_constant<bool, value> 的特化版本,其中 std::true_type 是 std::integral_constant<bool, true>,std::false_type 是 std::integral_constant<bool, false>。這兩種類型的主要用途是表示編譯期的布爾值。在模板元編程中,它們常被用來(lái)代表一種編譯期的"是"和"否",從而允許我們進(jìn)行編譯期的條件判斷。同時(shí),由于它們都是類型,因此也可以作為類型標(biāo)簽來(lái)使用,幫助我們?cè)谀0逶幊讨袀鬟f信息。
通過(guò)這樣的設(shè)計(jì),std::integral_constant能夠讓我們?cè)诰幾g期間就能確定某些值,從而提高代碼的效率。同時(shí),因?yàn)樗酥殿愋偷男畔ⅲ覀冞€可以根據(jù)這個(gè)信息進(jìn)行編程,提高代碼的靈活性。
通過(guò)上述的解釋和分析,我們可以很清楚的理解了std::is_object的含義了。
3.使用
std::is_object主要用于元編程中的類型檢查,以便在編譯時(shí)確定某個(gè)類型是否符合限制條件。使用方法也比較簡(jiǎn)單,只需在代碼中調(diào)用std::is_object<>模板,并傳入要檢查的類型名,即可獲得該類型是否為對(duì)象類型的結(jié)果。示例如下:
template <typename T>
void calc(){
static_assert(std::is_object<T>::value, "T must be an object type.");
//...
}
class MyTest{};
int main(){
calc<int>();
MyTest x;
func<decltype(x)>();
calc<int&>(); //compile error
return 0;
}
上述代碼中,定義了一個(gè)模板函數(shù)calc,該函數(shù)要求其參數(shù)類型必須是對(duì)象類型。在模板函數(shù)中使用了std::is_object<>模板,來(lái)檢查模板參數(shù)類型是否為對(duì)象類型。如果不是,將會(huì)拋出一個(gè)編譯器錯(cuò)誤。這樣,就能夠在編譯期間檢測(cè)到錯(cuò)誤的使用,減少運(yùn)行時(shí)錯(cuò)誤的概率。
使用注意:1)std::is_object判斷的是類型是否為對(duì)象類型,而非是否為類類型或枚舉類型。 2)使用std::is_object模板時(shí),需要注意傳入的類型名中不要包含已刪除的引用和cv限定符。示例如下:
#include<iostream>
#include<type_traits>
struct MyStruct{};
enum class MyEnum{A,B};
int main(){
std::cout << std::is_object<MyStruct>::value << std::endl; //true
std::cout << std::is_object<MyEnum>::value << std::endl; //true
std::cout << std::is_object<int>::value << std::endl; //true
std::cout << std::is_object<const int>::value << std::endl; //true
std::cout << std::is_object<const int&>::value << std::endl; //false
std::cout << std::is_object<const volatile int>::value << std::endl; //true
return 0;
}4.總結(jié)
std::is_object是一個(gè)用于元編程的C++類型特性,用于判斷一個(gè)類型是否是對(duì)象類型。只需在代碼中調(diào)用std::is_object<>模板,并傳入要檢查的類型名,即可判斷該類型是否為對(duì)象類型。在編寫(xiě)代碼時(shí),需要注意std::is_object判斷的是類型是否為對(duì)象類型,而不是類類型或枚舉類型。同時(shí),在使用std::is_object模板進(jìn)行類型檢查時(shí),需要注意傳入的類型名中不要包含已刪除的引用和cv限定符。通過(guò)合理使用std::is_object模板,可以在編譯期間檢測(cè)到錯(cuò)誤的使用,減少運(yùn)行時(shí)錯(cuò)誤的概率,提高代碼穩(wěn)定性。
到此這篇關(guān)于C++中std::is_object的具體使用的文章就介紹到這了,更多相關(guān)C++ std::is_object內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- C++中std::find函數(shù)介紹和使用場(chǎng)景
- C++中std::count函數(shù)介紹和使用場(chǎng)景
- C++ std::any的模擬實(shí)現(xiàn)
- 深入理解C++中std::chrono庫(kù)的使用
- C++17中std::byte的具體使用詳解
- C++ std::make_unique和std::make_shared用法小結(jié)
- C++中std::chrono時(shí)間庫(kù)的全面解析
- C++筆記之std::future的用法小結(jié)
- C++ std::unique_lock 用法實(shí)例詳解
- C++的std::transform()的實(shí)現(xiàn)
- C++中std::sort函數(shù)介紹和使用場(chǎng)景
相關(guān)文章
貪心算法的C語(yǔ)言實(shí)現(xiàn)與運(yùn)用詳解
這篇文章主要介紹了貪心算法的C語(yǔ)言實(shí)現(xiàn)與運(yùn)用詳解,運(yùn)用么,就是文中所附的ACM練習(xí)題,哈哈:D需要的朋友可以參考下2015-08-08
C++小知識(shí):用合適的工具來(lái)分析你的代碼
今天小編就為大家分享一篇關(guān)于C++小知識(shí):用合適的工具來(lái)分析你的代碼,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-01-01
C++如何實(shí)現(xiàn)簡(jiǎn)易掃雷游戲
這篇文章主要為大家詳細(xì)介紹了C++如何實(shí)現(xiàn)簡(jiǎn)易掃雷游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-03-03
C語(yǔ)言修煉之路初識(shí)指針陰陽(yáng)竅?地址還歸大道真下篇
指針是指向另一個(gè)變量的變量。意思是一個(gè)指針保存的是另一個(gè)變量的內(nèi)存地址。換句話說(shuō),指針保存的并不是普通意義上的數(shù)值,而是另一個(gè)變量的地址值。一個(gè)指針保存了另一個(gè)變量的地址值,就說(shuō)這個(gè)指針“指向”了那個(gè)變量2022-02-02
C語(yǔ)言多功能動(dòng)態(tài)通訊錄實(shí)現(xiàn)示例
這篇文章主要為大家介紹了C語(yǔ)言多功能動(dòng)態(tài)通訊錄實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01
C++ 關(guān)于 CMFCPropertyGridCtrl 的使用方法
這篇文章主要介紹了C++ 關(guān)于 CMFCPropertyGridCtrl 的使用方法的相關(guān)資料,需要的朋友可以參考下2015-06-06
C++ 配置文件管理神器 yaml-cpp 實(shí)戰(zhàn)指南
本文主要介紹了C++ 配置文件管理神器 yaml-cpp 實(shí)戰(zhàn)指南,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2026-05-05
C++實(shí)踐Time類中的運(yùn)算符重載參考方法
今天小編就為大家分享一篇關(guān)于C++實(shí)踐Time類中的運(yùn)算符重載參考方法,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-02-02

