任何人都可以向我解释函数poiner的优点吗?
我知道我的问题有很多可能的重复,但他们只用文字解释,这不是很有帮助,我需要一个案例的例子,不使用函数指针与使用函数指针的情况比较。 / p>
非常感谢。
答案 0 :(得分:1)
如何将数据映射到行为,例如:
void DoIt();
void DontDoIt();
std::map<std::string, std::function<void()> word_map {
{"DoIt", DoIt},
{"DontDoIt", DontDoIt}
};
std::string word;
// ... get "DoIt" or "DontDoIt" into word
word_map[word](); // execute correct function
答案 1 :(得分:0)
简单示例:假设您有N个记录,包括姓名和电话号码。
你被要求排序
一个不错的方法就是改变在排序例程中作为函数指针传递的比较函数。
void sort( records r[], int N,
bool (*fptr)( const record& lhs, const record& rhs ) ) { }
如果你不使用函数指针,你最终只会为两个不同的比较函数编写相同的逻辑。
void sort_by_name( records r[], int N) { }
void sort_by_phoneno( records r[], int N) { }
答案 2 :(得分:0)
通过使用函数指针,您可以避免代码重复。
没有函数指针:
void AddOneToVectorElements( vector<int> v )
{
// implementation
}
void MultiplyVectorElementsByTwo( vector<int> v )
{
// implementation
}
// usage
AddOneToVectorElements(v);
MultiplyVectorElementsByTwo(v);
使用函数指针:
typedef int (*func)(int);
int TransformVecotr ( vector<int> v, func f)
{
// implementation by application of f to every element
}
int AddOne(int x)
{
return x + 1;
}
int MultiplyByTwo(int x)
{
return 2 * x;
}
// usage
TransformVecotr(v, &AddOne);
TransformVecotr(v, &MultiplyByTwo);
在C ++ 11中有lambda函数,它们使整个事情变得更加方便。
答案 3 :(得分:0)
关键是函数指针一直在通用编程中“在引擎盖下”使用。人们往往会忘记这一点,因为模板参数推导隐藏了函数指针语法。
例如:
#include <algorithm>
#include <iterator>
bool f(int i)
{
return i == 1;
}
int main()
{
int arr[] = { 1, 1, 3 };
int count = std::count_if(std::begin(arr), std::end(arr), f);
}
f
的最后一行中的main
是一个函数指针,因为std::count_if
模板函数将接受可以与{一起使用的任何内容{1}}语法。引用cppreference.com:
()
template< class InputIt, class UnaryPredicate >
typename iterator_traits<InputIt>::difference_type
count_if( InputIt first, InputIt last, UnaryPredicate p );
可以是函数指针,在上面的示例中是一个。
当您通过UnaryPredicate
时,编译器会自动推断出其确切类型bool(*)(int)
。从技术上讲,你也可以像这样写电话:
f
如果C ++中没有函数指针,那么就不能直接将函数用作标准库算法中的谓词。你必须始终将它们包装在类中:
// just for illustration:
std::count_if<int*, bool(*)(int)>(std::begin(arr), std::end(arr), f);