Templates 函数指针作为模板参数:调用约定(cdecl/stdcall)是否可以扣除?
我有一节这样的课Templates 函数指针作为模板参数:调用约定(cdecl/stdcall)是否可以扣除?,templates,c++14,calling-convention,Templates,C++14,Calling Convention,我有一节这样的课 /** Some third party libraries with C interfaces have their own set of functions to allocate and free heap memory buffers aligned to the specification of the library. This class helps to manage such buffers in a convenient RAII style
/**
Some third party libraries with C interfaces have their own set of functions to allocate and free
heap memory buffers aligned to the specification of the library. This class helps to manage such
buffers in a convenient RAII style
@tparam Type The type of data to hold in the buffer
@tparam SizeType The type used for sizes (in most cases either int or size_t)
@tparam allocFunction A function to call that takes the number of bytes to allocate as argument and returns a pointer
of Type* to the allocated memory
@tparam freeFunction A function to call that takes a void* pointer and frees the previously allocated memory
*/
template <typename Type, typename SizeType, Type* (*allocFunction)(SizeType), void (*freeFunction)(void*)>
class GenericScopedBuffer
导致编译器错误,如C2440:“专用化”:无法从“void(\u stdcall*)(void*)”转换为“void(\u cdecl*)(void*)”
显而易见的原因是x86编译器假定这样声明的函数指针是指向\uu cdecl
函数的指针。现在,由于这个类模板实际上应该与任何类型的函数的函数指针一起工作,我想知道是否有一种方法可以从传入的函数中扣除调用约定类型。然而,stdcall或cdecl不是真正的类型,而是更像编译器的提示,对吗
那么,以跨平台和通用的方式实现这一点的好方法是什么呢?void(\uu stdcall*)(void*))
和void(\uu cdecl*)(void*)
就MSVC而言是两种不同的类型。这些限定符是指定语言链接的一种预标准方法。回想一下,extern“C”
函数不同于extern“C++”
函数,后者不同于extern“FORTRAN”
函数,即使有些编译器允许您将它们混在一起
有几种方法可以解决这个问题
您可以将模板专门用于\uu cdecl
功能
您可以告诉编译器您不在乎类型是什么:
template <auto allocFunction, auto freeFunction> class GenericScopedBuffer
假设默认约定为
cdecl
,则在编写函数模板时,它会自动添加\uu cdecl
\uuu cdecl
和\uu stdcall
不仅仅是提示,而是函数的构建和调用方式,这就是为什么您不能在cdecl
函数和stdcall
函数之间转换,而不会得到一些堆栈错误。相反,您可以使用一个简单的typename
并用std::is_function
检查它。是的,我知道\uu cdecl
和\uu stdcall
之间的根本区别。然而,“您可以使用一个简单的typename并用std::is_函数检查它”是什么意思。你能给我一些简短的演示代码来详细说明一下吗?谢谢。不幸的是,我们使用的是C++14,而自动模板参数是C++17的一项功能–我更新了原始问题上的标记,否则这将是我选择的解决方案。“愚蠢的宏”解决方案似乎是一条路要走,尽管它取决于愚蠢的宏:D——我更喜欢避免它
template <auto allocFunction, auto freeFunction> class GenericScopedBuffer
template <typename AllocFuncT, AllocFuncT allocFunction,
typename FreeFuncT, FreeFuncT freeFunction> class GenericScopedBuffer
#define TV(x) decltype(x), (x)