问题描述
考虑下面关于Win32的运行时动态链接机制的包装:
Consider the following wrapper around Win32's Runtime Dynamic Linking mechanism:
#include <boost/noncopyable.hpp>
#include <windows.h>
#include "Exception.hpp"
namespace WindowsApi
{
class RuntimeDynamicLinker : boost::noncopyable
{
HMODULE hMod_;
public:
RuntimeDynamicLinker(const wchar_t * moduleName)
{
hMod_ = LoadLibraryW(moduleName);
if (hMod_ == 0)
{
Exception::Throw(GetLastError());
}
}
template <typename T>
T GetFunction(const char* functionName)
{
FARPROC result = GetProcAddress(hMod_, functionName);
if (result == 0)
{
Exception::Throw(GetLastError());
}
return reinterpret_cast<T>(result);
}
~RuntimeDynamicLinker()
{
FreeLibrary(hMod_);
}
};
}
和客户端示例:
typedef NTSTATUS (NTAPI * NtQueryInformationProcess_t)(
IN HANDLE,
IN PROCESS_INFORMATION_CLASS,
OUT PVOID,
IN ULONG,
OUT PULONG);
RuntimeDynamicLinker ntdll(L"ntdll.dll");
NtQueryInformationProcess_t NtQueryInformationProcess =
ntdll.GetFunction<NtQueryInformationProcess_t>("NtQueryInformationProcess");
基本上,如果任何人试图使用 GetFunction
其中 T
是除了函数指针类型之外的任何其他类型(因为 reinterpret_cast
I '
Basically, I'd like to add an error message if anyone tries to use GetFunction
where T
is anything other than a function pointer type (because the reinterpret_cast
I'm forced to use here could otherwise hide user errors).
通过boost类型特性挖掘,我发现现在有一个模板。但是, is_function
接受对函数的引用,这将是我的情况下的用户错误(仅函数指针)。
Digging through boost type traits, I did find that there's an existing is_function
template. However, is_function
accepts references to functions, which would be a user error in my case (function pointers only).
如何修改 RuntimeDynamicLinker :: GetFunction< T>()
,以产生一个合理可理解的编译器错误信息,如果 T
不是函数指针类型?
How can I modify RuntimeDynamicLinker::GetFunction<T>()
to produce a reasonably understandable compiler error message if T
is not a function pointer type?
(注意:我从来没有做过任何类型的TMP,所以不要害怕
(Side note: I've never done any kind of TMP, so don't be afraid to go over things that are "basic" to regular users of TMP)
推荐答案
您可以使用 is_pointer< T> :: value&& is_function< remove_pointer< T> :: type> :: value
in a static_assert
/ BOOST_STATIC_ASSERT
。
You could use is_pointer<T>::value && is_function<remove_pointer<T>::type>::value
in a static_assert
/BOOST_STATIC_ASSERT
.
这篇关于我如何(在编译时)确定typename是否是一个函数指针typename?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!