remove_pointer使用测验

一、问题引入

        有如下一段代码:

1 auto MakeGuard(HINTERNET hinternet)
2 {
3     if(!hinternet) {
4         const DWORD ec = ::GetLastError();
5         throw std::system_error(ec, std::system_category(), "HINTERNET object creation failed.");
6     }
7     return std::unique_ptr<std::remove_pointer_t<HINTERNET>, decltype(&WinHttpCloseHandle)>(hinternet, WinHttpCloseHandle);
8 }        

  该函数的作用是将HINTERNET对象放到智能指针对象中并自定义删除该对象的删除器(仿函数,函数对象等),其中std::remove_pointer_t<HINTERNET>起到什么作用呢?

二、std::remove_pointer

  该函数是一个模板函数,移除T类型的指针类型,如果T类型不是指针,那么去除的类型与T类型相同。例如:

std::remove_pointer<int>::type() ==> int
std::remove_pointer<int*>::type() ==> int
std::remove_pointer<int**>::type() ==> int*
std::remove_pointer<const int*>::type ==>int
std::remove_pointer<int* const>::type ==>int

  cppreference 对remove_pointer_t 定义 : using remove_pointer_t typename remove_pointer<T>::type,所以为了代码简洁,上面例子也可写成如下:

std::remove_pointer_t<int> ==> int
std::remove_pointer_t<int*> ==> int
std::remove_pointer_t<int**> ==> int*
std::remove_pointer_t<const int*> ==>int
std::remove_pointer_t<int* const> ==>int

  所以,最上面的那一段代码中 std::unique_ptr<std::remove_pointer_t<HINTERNET>, decltype(&WinHttpCloseHandle)>(hinternet, WinHttpCloseHandle); 其实就是创建unique_ptr<T, Deleter>智能指针对象的构造函数。例如:

int* pValue = &value;
std::unique_ptr<std::remove_pointer_t<int*>(), decltype<&f>>(pValue, f); ==> std::unique_ptr<int, decltype<&f>>(value, f);

 三、测试验证

  std::remove_pointer的使用验证代码如下:

 1 int value = 10;
 2 auto removeValue1 = std::remove_pointer<decltype(value)>::type();
 3 std::cout << "removeValue1 type : " << typeid(removeValue1).name() << "
";
 4 int* pValue = &value;
 5 auto remoteValue2 = std::remove_pointer<decltype(pValue)>::type();
 6 std::cout << "removeValue2 type : " << typeid(remoteValue2).name() << "
";
 7 int** ppValue = &pValue;
 8 auto remoteValue3 = std::remove_pointer<decltype(ppValue)>::type();
 9 std::cout << "removeValue3 type : " << typeid(remoteValue3).name() << "
";
10 const int* pcValue = pValue;
11 auto remoteValue4 = std::remove_pointer<const int*>::type();
12 std::cout << "removeValue4 type : " << typeid(remoteValue4).name() << "
";
13 int* const cpValue = pValue;
14 auto remoteValue5 = std::remove_pointer<int* const>::type();
15 std::cout << "removeValue4 type : " << typeid(remoteValue5).name() << "
";

  std::unique_ptr<std::remove_pointer_t<HINTERNET>, decltype(&WinHttpCloseHandle)>(hinternet, WinHttpCloseHandle)验证

1 void Close(int* param)
2 {
3   std::cout << "Close function. " << typeid(param).name() << "param " << param << "
";
4 }
5 
6 auto MakeGuard(int* h)
7 {
8   return std::unique_ptr<std::remove_pointer_t<decltype(h)>, decltype(&Close)>(h, Close); // return std::unique_ptr<int, deleter>();
9 }
1 int value = 10;
2 int* pValue = &value;
3 
4 auto h = MakeGuard(pValue);

  上面就是对std::remove_pointer模板函数的介绍,细心的同学可能会注意到MakeGurad函数还涉及到auto和decltype关键字的使用,后面会进行相关介绍。

原文地址:https://www.cnblogs.com/smartNeo/p/14510114.html