使用C ++中的函数typedef定义函数

时间:2013-05-07 05:10:01

标签: c++ visual-studio-2012 typedef

我正在Windows中实现一项服务。 VisualStudio 2012具有以下函数typedef:

typedef VOID WINAPI SERVICE_MAIN_FUNCTIONW (
    DWORD dwNumServicesArgs,
    LPWSTR *lpServiceArgVectors
);

还有一个函数指针typedef:

typedef VOID (WINAPI *LPSERVICE_MAIN_FUNCTIONW)(
    DWORD   dwNumServicesArgs,
    LPWSTR  *lpServiceArgVectors
);

如何使用typedef?

定义具有此函数签名的函数

5 个答案:

答案 0 :(得分:6)

引用当前的C ++标准(C ++ 11):

[dcl.fct] / 10

  

函数类型的typedef可用于声明函数,但不得用于定义函数(8.4)。   [实施例:

typedef void F();
F fv;             // OK: equivalent to void fv();
F fv { }          // ill-formed
void fv() { }     // OK: definition of fv
     

-end example]

也就是说,您可以使用typedef声明但不能定义函数。您必须明确指定签名,请参阅Alex Farber的答案。


在某种程度上,您可以使用typedef来“定义”该函数,但它涉及一些模板魔法。这是一个有趣的例子,表明你可以用它来定义一个函数。

// extra definitions for SSCCE
  typedef unsigned int DWORD;
  typedef wchar_t* LPWSTR;
  #define VOID void
  #define WINAPI

// function ptr
typedef VOID (WINAPI *LPSERVICE_MAIN_FUNCTIONW)(
    DWORD   dwNumServicesArgs,
    LPWSTR  *lpServiceArgVectors
);

// function typedef
typedef VOID WINAPI SERVICE_MAIN_FUNCTIONW (
    DWORD dwNumServicesArgs,
    LPWSTR *lpServiceArgVectors
);


template < typename... TT >
struct disassemble_funcptr
{};
template < typename Ret, typename... Args >
struct disassemble_funcptr < Ret(Args...) >
{
    typedef Ret return_type;

    static Ret Func(Args...)
    {
        /* your code here */
    }
};

// using the typedef SERVICE_MAIN_FUNCTIONW to define the function
LPSERVICE_MAIN_FUNCTIONW my_func_ptr =
  & disassemble_funcptr < SERVICE_MAIN_FUNCTIONW > :: Func;

int main()
{
    LPWSTR str = nullptr;
    my_func_ptr(42, &str);
}

答案 1 :(得分:1)

使用typedef,函数不能定义 (或声明)。它必须以传统方式定义。 e.g。

void foo (type1 t1, type2 t2) // t1 and t2 are objects which can be ... 
{                             // ... visible only in conventional way
  ...
}

函数指针typedef可以声明函数指针,可以使用函数的地址指定:

typedef void (*PF)(type1, type2);
PF pf = &foo;

答案 2 :(得分:1)

您不需要(也不能)在函数定义中使用typedef。要创建服务主函数,只需写:

VOID WINAPI SvcMain( DWORD dwNumServicesArgs, LPWSTR *lpServiceArgVectors )
{
    // ...
}
Windows内部使用

LPSERVICE_MAIN_FUNCTIONW来调用每个服务起始点。通常,您需要函数指针typedef来调用,而不是定义函数。

答案 3 :(得分:0)

使用C ++ 11,您可以使用具有空捕获列表的lambdas可转换为函数指针的事实来声明和定义与一个表达式中的函数typedef匹配的函数,例如:

using my_function_t = void(*)(int,int);

my_function_t add_function = [](int x, int y) { return x + y; };

答案 4 :(得分:0)

这可以通过反转尝试的方法来实现。

  • 定义一个扩展为所需类型的宏
#define defLedClkFunc(name)   void (name)(uint16_t led)
  • 使用宏来定义你的 typedef
typedef defLedClkFunc(tLedClkFunction);
  • 在声明函数实现时使用宏
//********************************************************
//
// Declaration of first function
//
defLedClkFunc(ledClkEnable)
{
  // Body of first function
} // ledClkEnable()

//********************************************************
//
// Declaration of second function
//
defLedClkFunc(ledClkDisable)
{
  // Body of second function
} // ledClkDisable()

//
// Create an array of pointers to the functions
//
tLedClkFunction *myFuncs[] = {
                             ledClkEnable,
                             ledClkDisable,
                             };

现在您有了函数签名的单点定义,对签名的任何更改都会通过所有类型定义和函数声明传播。

我发现这对于定义函数集(例如中断处理程序、消息处理程序)非常有用。

此外,如果有人决定它们都应该有一些任意的前缀和/或后缀,则宏使得更改 *all 函数名称变得微不足道。只需使用标记粘贴作为宏定义的一部分,并在 name 周围粘贴所需的前缀/后缀。

需要记住创建的数据类型,以便操作指向函数的指针,但即使这样也可以通过少量的附加宏进行自动调整-魔法。