是否可以将指针视为非类型模板参数中的整数类型?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了是否可以将指针视为非类型模板参数中的整数类型?相关的知识,希望对你有一定的参考价值。
我正在尝试创建一个模板,其中默认值可以作为非类型参数传递。
原始类型(WINAPI的HANDLE
)是从编译器角度来看的指针类型,但从用户角度来看则被视为整数类型。
// Somewhere in system headers
#define INVALID_HANDLE_VALUE ((HANDLE)(LONG_PTR)-1)
typedef void *HANDLE;
// My code
template<typename Handle, Handle Default>
class HandleWrapper
{
...
};
HandleWrapper<HANDLE, INVALID_HANDLE_VALUE>; // error: invalid nontype template argument of type `HANDLE`
我目前的解决方法:
template<typename Handle, uintptr_t Default>
class HandleWrapper
{
static_assert(std::is_pointer<Handle>::value, "Handle must be a pointer");
static constexpr Handle DefaultHandle = reinterpret_cast<Handle>(Invalid);
};
我想正确的解决方案是以某种方式指定typename Handle
应该被视为一个整数类型(uintptr_t
),只要会话没有缩小。
答案
在我的代码中,我有一个模板化的句柄包装类,我使用它,但我采用不同于你的方法。我为每个要包装的句柄类型定义了一个单独的traits
类,然后使用template参数指定在包装器中使用哪些特征。
尝试在你的情况下做类似的事情,例如:
struct InvalidHandleTraits
{
using HandleType = HANDLE;
static constexpr HANDLE DefaultHandle = INVALID_HANDLE_VALUE;
//...
static void Close(HANDLE h) { CloseHandle(h); }
//...
};
struct NullHandleTraits
{
using HandleType = HANDLE;
static constexpr HANDLE DefaultHandle = NULL;
//...
static void Close(HANDLE h) { CloseHandle(h); }
//...
};
... other traits as needed...
template<typename traits = InvalidHandleTraits>
class HandleWrapper
{
public:
using HandleType = typename traits::HandleType;
HandleWrapper(HandleType h = traits::DefaultHandle) : m_handle(h) { std::cout << "constructor: " << h << std::endl; }
~HandleWrapper() { traits::Close(m_handle); }
//...
operator HandleType() { return m_handle; }
private:
HandleType m_handle;
};
然后你可以在需要时使用所需的traits
类,例如:
HandleWrapper<> h = CreateFile(...);
// or:
// HandleWrapper<InvalidHandleTraits> h = CreateFile(...);
HandleWrapper<NullHandleTraits> h = CreateFileMapping(...);
以上是关于是否可以将指针视为非类型模板参数中的整数类型?的主要内容,如果未能解决你的问题,请参考以下文章