[英]Order of definition for function signatures in C++
我有一個函數指針表,並且試圖確定定義函數簽名的順序是否重要。 看下面的示例,我想知道為什么Method 1
無法編譯,即使可以通過decltype確定其函數指針類型。 我想知道如何使Method 1
起作用。 有任何想法嗎? 謝謝。
// Method 1
typedef struct FOO_FUNCS
{
void( WINAPI * pfnFoo) ();
} FOO_FUNCS;
typedef decltype(&FOO_FUNCS::pfnFoo) PFN_FOO;
// Method 2
typedef void (WINAPI* PFN_BAR)();
typedef struct BAR_FUNCS
{
PFN_BAR pfnBar;
} BAR_FUNCS;
class FooBarClass
{
public:
static void WINAPI Foo()
{
cout << "Foo" << "\n";
}
static void WINAPI Bar()
{
cout << "Bar" << "\n";
}
};
int _tmain(int argc, _TCHAR* argv[])
{
void* pfnFoo = reinterpret_cast<void*>(FooBarClass::Foo);
reinterpret_cast<PFN_FOO>(pfnFoo) (); <= = this gives me "error C2440 : 'reinterpret_cast' : cannot convert from 'void *' to 'PFN_FOO'"
void* pfnBar = reinterpret_cast<void*>(FooBarClass::Bar);
reinterpret_cast<PFN_BAR>(pfnBar) ();
}
擴展typedef和decltype之后, PFN_FOO
是指向 FOO_FUNCS
成員的指針,該成員的類型是指向void WINAPI ()
指針。 您不能在指向member的指針和void*
之間轉換。 這就是為什么您得到錯誤。
我不確定,但我相信您可能一直在尋找以下其中一項:
typedef decltype(FOO_FUNCS().pfnFoo) PFN_FOO;
typedef decltype(&FOO_FUNCS().pfnFoo) PFN_FOO;
(通常,您最好使用std::declval<FOO_FUNCS>()
而不是上面的FOO_FUNCS()
,因為它不需要可訪問的默認構造函數)。
也許是最簡單的(感謝@ Jarod42):
typedef decltype(FOO_FUNS::pfnFoo) PFN_FOO;
以下是每個typedef的詳細信息:
decltype(FOO_FUNCS().pfnFoo)
表達式是FOO_FUNCS().pfnFoo
。 也就是說,創建一個默認構造的FOO_FUNCS
對象並訪問其數據成員pfnFoo
。 應用於此類表達式的decltype()
產生數據成員的類型,該類型為void( WINAPI * ) ()
。 這是不帶任何參數並返回void
的WINAPI
函數的指針。
decltype(&FOO_FUNCS().pfnFoo)
表達式是&FOO_FUNCS().pfnFoo
。 也就是說,創建一個默認構造的FOO_FUNCS
對象,訪問其數據成員pfnFoo
並獲取其地址(在內存中)。 該類型是“指向pfnFoo
類型的指針”。 這意味着此decltype等效於decltype(FOO_FUNCS().pfnFoo) *
。 因此它是void( WINAPI * * ) ()
-指向不帶任何參數並返回void
的WINAPI
函數的指針的指針。
decltype(FOO_FUNCS::pfnFoo)
表達式是FOO_FUNCS::pfnFoo
。 即,將數據成員pfnFoo
為類FOO_FUNCS
。 decltype()
產生此數據成員的類型,它也是void( WINAPI * ) ()
-指向不帶參數且返回void
的WINAPI
函數的指針。
和您原來的一個:
decltype(&FOO_FUNCS::pfnFoo)
表達式是&FOO_FUNCS::pfnFoo
。 也就是說,采用指向類FOO_FUNCS
成員pfnFoo
的指針(有時不正確地稱為“成員指針”)。 類型為void (WINAPI (FOO_FUNCS::*)*) ()
-指向類FOO_FUNCS
成員的指針,其中該成員具有指向WINAPI
函數的類型指針,該指針不帶任何參數並返回void
。
最后一個本質上是不同的-另一個只是以不同的方式來訪問該成員作為變量(通過臨時的,通過限定的名稱)(如果需要的話)的物理方式。 最后一個將其視為“邏輯”成員,作為類中的“偏移”。 這和指針( T*
)和指向類X
成員的指針( TX::*
)的基本區別相同。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.