基本形式
#include <iostream>
#include <functional>
/**
* 1. C++11新增的類型別名聲明方式
*/
using pFunc1 = void(); //普通函數
using pFunc2 = void(int, int); //帶參數的函數
using pFunc3 = int(int, int); //帶參數和返回值的函數
using pFunc4 = void* (); //返回指針的函數
using pFunc5 = const char* (); //返回常量(底層)指針的函數
using pFunc6 = char* const(); //返回常量(頂層)指針的函數
using pFunc7 = const char* const(); ; //返回常量指針(底層+頂層)的函數
std::function<void()> f1;
std::function<void(int, int)> f2;
std::function<int(int, int)> f3;
std::function<void* ()> f4;
std::function<const char* ()> f5;
std::function<char* const()> f6;
std::function<const char* const()> f7;
/**
* 測試函數
*/
void func1()
{
std::cout << __FUNCTION__ << std::endl;
}
void func2(int x, int y)
{
std::cout << __FUNCTION__ << std::endl;
}
int func3(int x, int y)
{
std::cout << __FUNCTION__ << std::endl;
return 0;
}
void* func4()
{
std::cout << __FUNCTION__ << std::endl;
return nullptr;
}
const char* func5()
{
std::cout << __FUNCTION__ << std::endl;
return nullptr;
}
char* const func6()
{
std::cout << __FUNCTION__ << std::endl;
return nullptr;
}
const char* const func7()
{
std::cout << __FUNCTION__ << std::endl;
return nullptr;
}
int main(int argc, char* argv[])
{
f1 = func1;
f2 = func2;
f3 = func3;
f4 = func4;
f5 = func5;
f6 = func6;
f7 = func7;
//以下均屬出自身函數名(func1, func2...)
f1();
f2(0, 0);
f3(0, 0);
f4();
f5();
f6();
f7();
//可查看封裝的函數指針類型
std::cout << f1.target_type().name() << std::endl;
std::cout << f5.target_type().name() << std::endl;
std::cout << f4.target_type().name() << std::endl;
//可使用target查看封裝的函數指針地址(模板參數不能使用類型別名聲明的類型)
auto p1 = f1.target<void(*)()>();
std::cout << p1 << std::endl;
auto p7 = f7.target<const char* const(*)()>();
std::cout << p7 << std::endl;
/**
* std::function支持拷貝,移動操作,在此不做贅述
*
*/
return 0;
}
其他
當遇到重載函數需要用std::function封裝時,為避免編譯時出現二義性問題(模板類的類型在編譯後才會知道),將它們改寫為lambda表達式或者函數指針的形式後再進行封裝。