Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Templates 函数指针作为模板参数:调用约定(cdecl/stdcall)是否可以扣除?_Templates_C++14_Calling Convention - Fatal编程技术网

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)