2011-11-22 88 views
4

參考:[33.11] Can I convert a pointer-to-function to a void*?當p是函數指針時,我們應該使用p(..)還是(* p)(..)?

#include "stdafx.h" 
#include <iostream> 

int f(char x, int y) { return x; } 
int g(char x, int y) { return y; } 

typedef int(*FunctPtr)(char,int); 

int callit(FunctPtr p, char x, int y) // original 
{ 
    return p(x, y); 
} 

int callitB(FunctPtr p, char x, int y) // updated 
{ 
    return (*p)(x, y); 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    FunctPtr p = g;     // original 
    std::cout << p('c', 'a') << std::endl; 

    FunctPtr pB = &g;     // updated 
    std::cout << (*pB)('c', 'a') << std::endl; 

    return 0; 
} 

問題>哪種方式,原來的或更新的,是推薦的方法? 我已經用VS2010測試了兩種方法,並且每個都打印出正確的結果。

謝謝

雖然我確實看到在原來的職位以下用法:

void baz() 
{ 
    FredMemFn p = &Fred::f; ← declare a member-function pointer 
    ... 
} 
+1

指針到成員函數是**完全不同的主題**。我在[我的這個答案]結尾簡要地提到了它們(http://stackoverflow.com/q/8198062/596781)。 –

+1

你應該使用'(******************* p)()',顯然! –

回答

6

解引用函數指針產生另一個函數指針。所以,只是f(),否則你只是混淆了你的代碼。

指向成員的指針是完全不同的動物。他們要求使用.*->*運營商。這也是爲什麼你應該使用std::function(或boost::function)而不是指向函數/成員的原始指針。

+3

也許人們應該考慮到'std :: function'會帶來相當大的開銷,所以在緊縮時,一個直接的PTMF可能更可取。 –

+0

@KerrekSB你知道最近的基準嗎?我發表了一篇關於codeproject的文章,它提供了一個hacky快速代理以及bechmarks的實現,但它的數據是相當老的IIRC。 –

+1

@TamásSzelei:不用擔心,但是我知道'std :: function'基本上被設計爲在內部使用類型擦除,這需要虛擬調度和動態分配,並且我有一種預感,即由於基本原因無法對其進行優化。所以,如果你處於一個緊張的循環或者需要記憶的地方,那麼可能會付出真正的代價。不過,我也很想看看比較。 –

0

您可以使用的形式,但它看起來最自然的(對我來說)使用此:

p(x, y); 
6

兩者都是好的:

p(); 
(*p)(); 

但第一個是最好的,因爲它與函子對象更一致。例如,您可以編寫一個函數模板:

template<typename Functor> 
void f(Functor fun) 
{ 
    fun(); //uniform invocation - it doesn't matter what it is. 
} 

現在,這可以用函數指針調用,並函子對象,兩者已成爲可能只是因爲我已經使用第一種語法。

故事的寓意是:爭取統一調用。不管調用實體是函數指針還是函數對象,都要以調用語法應該相同的方式編寫代碼。

+0

我測試過'* p()'和VS2010報告'錯誤C2100:非法間接' – q0987

+0

@ q0987:是的。我錯了。這是不允許的。我糾正了我的答案。 – Nawaz

1

該標準允許所有的使用形式,但是除非你想 讀者糊塗,通常最好是明確的:&f取功能的 地址,並(*p)(x, y)調用它。

+0

我早就聽說過這個地方。 – q0987

相關問題