2016-02-03 82 views
3

參照下面的代碼函數和函數指針在C++

#include <iostream> 
using std::cout; 
using std::endl; 
#include <vector> 
using std::vector; 

void function() { 
    cout << "Hello World" << endl; 
} 

int main() { 
    vector<void (*)()> functions; 
    functions.push_back(function);   // (1) no error 
    functions.push_back(&function);  // (2) no error 
    for (const auto& func : functions) { 
     func(); 
    } 

    // vector<decltype(function)> vec;  // (3) error 
    return 0; 
} 

似乎當我取消(3),我只是想了解這背後的原因是一個錯誤。當我傳遞一個函數作爲模板函數的參數時,它是否將類型解析爲函數指針?編譯器將所有函數類型推導爲函數指針是合理的,但爲什麼decltype()不解析爲函數指針呢?

+1

我沒有一個答案,但我建議使用'std :: function'而不是函數指針。它更具可讀性,並且不會處理它是否是指針。 –

+0

@AdiLevin'std :: function'應該只在需要的時候使用,也就是當一個真正想要存儲(!)沒有共同但可以被調用的調用(使用相應的參數,返回相應的類型)時。它增加了很多開銷。 –

回答

7

decltype(function)void() - 一個函數。
你需要的是一個函數的腐朽版本 - void(*)()

std::decay<decltype(function)>::type 

std::vector < std::decay<decltype(function)>::type > myPtrFunctionVec; 

PS。
如果您正在使用VC++(visual stdio),則可以通過打印typeid(decltype(XXX)).name()輕鬆查看從decltype推導出的類型。與其他編譯器不同,VC++給出了一個類型的未修飾名稱。元編程調試非常方便。

編輯:
作爲@Daniel怨婦曾評論說,decltype(&function) workd爲好,解決方案,因爲構建&f使指針f,這是你所需要的

+4

'std :: decay'是個好主意,沒有想到它。你也可以'decltype(&function)':http://ideone.com/Af98uJ –

+0

@DanielJour酷!我不知道這個表達式會產生一個指向函數的指針! –

+1

@DavidHaim也不是我的。這是其中一件事情,你不會認爲會起作用,直到你再次看它,並意識到它是完全合理的。 '&function'是一個函數指針,所以邏輯上將它傳遞給'decltype'將評估函數指針的類型。雖然這太簡單了,但顯而易見。 –