C++中std::is_object的具體使用
1.概述
std::is_object是一種C++類型特性,其用途是判斷一個類型是否是一個對象類型(除了函數(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 。對于任何其他類型, 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++類型特征的基類。我們可以看到,這個模板類接受兩個參數(shù),一個類型_Ty和一個該類型的值_Val。它提供了一個靜態(tài)的常量成員value,該成員的值就是傳入的_Val;其中,using value_type = _Ty;和using type = integral_constant;分別用來定義value的類型以及integral_constant本身的類型。
然后,它還提供了兩個轉(zhuǎn)換函數(shù),一個是constexpr operator value_type() const noexcept,可以將std::integral_constant對象隱式轉(zhuǎn)換為T類型的值;另一個是constexpr value_type operator()() const noexcept,可以將std::integral_constant對象當作函數(shù)來調(diào)用,并返回其內(nèi)部保存的常量。
std::integral_constant 的兩個最常用的特化版本是 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>。這兩種類型的主要用途是表示編譯期的布爾值。在模板元編程中,它們常被用來代表一種編譯期的"是"和"否",從而允許我們進行編譯期的條件判斷。同時,由于它們都是類型,因此也可以作為類型標簽來使用,幫助我們在模板元編程中傳遞信息。
通過這樣的設計,std::integral_constant能夠讓我們在編譯期間就能確定某些值,從而提高代碼的效率。同時,因為它包含了值類型的信息,我們還可以根據(jù)這個信息進行編程,提高代碼的靈活性。
通過上述的解釋和分析,我們可以很清楚的理解了std::is_object的含義了。
3.使用
std::is_object主要用于元編程中的類型檢查,以便在編譯時確定某個類型是否符合限制條件。使用方法也比較簡單,只需在代碼中調(diào)用std::is_object<>模板,并傳入要檢查的類型名,即可獲得該類型是否為對象類型的結果。示例如下:
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; }
上述代碼中,定義了一個模板函數(shù)calc,該函數(shù)要求其參數(shù)類型必須是對象類型。在模板函數(shù)中使用了std::is_object<>模板,來檢查模板參數(shù)類型是否為對象類型。如果不是,將會拋出一個編譯器錯誤。這樣,就能夠在編譯期間檢測到錯誤的使用,減少運行時錯誤的概率。
使用注意:1)std::is_object判斷的是類型是否為對象類型,而非是否為類類型或枚舉類型。 2)使用std::is_object模板時,需要注意傳入的類型名中不要包含已刪除的引用和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.總結
std::is_object是一個用于元編程的C++類型特性,用于判斷一個類型是否是對象類型。只需在代碼中調(diào)用std::is_object<>模板,并傳入要檢查的類型名,即可判斷該類型是否為對象類型。在編寫代碼時,需要注意std::is_object判斷的是類型是否為對象類型,而不是類類型或枚舉類型。同時,在使用std::is_object模板進行類型檢查時,需要注意傳入的類型名中不要包含已刪除的引用和cv限定符。通過合理使用std::is_object模板,可以在編譯期間檢測到錯誤的使用,減少運行時錯誤的概率,提高代碼穩(wěn)定性。
到此這篇關于C++中std::is_object的具體使用的文章就介紹到這了,更多相關C++ std::is_object內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
C++從文本文件讀取數(shù)據(jù)到vector中的方法
這篇文章主要給大家介紹了利用C++如何從文本文件讀取數(shù)據(jù)到vector中,文章通過實例給出示例代碼,相信會對大家的理解和學習很有幫助,有需要的朋友們下面來一起看看吧。2016-10-10