pau*_*l23 10 c++ templates stl c++11 std-function
许多标准库算法都采用谓词函数.但是,这些谓词的类型是用户提供的任意模板参数.为什么C++ 11没有指定这些类型采用特定类型std::function?例如:
template< class InputIt >
InputIt find_if( InputIt first, InputIt last,
std::function<bool()> p );
Run Code Online (Sandbox Code Playgroud)
是不是使用这个而不是模板作为参数类型不是更干净?
Nic*_*las 10
std::function用于运行时多态性.任何特定的std::function实例都可以存储任何类型的仿函数(std::function当然,这种仿函数适合于签名).
标准库算法等根据其函数参数的类型进行模板化.因此,他们不需要运行时多态来完成他们的工作; 它们依赖于编译时多态性.
最重要的是,此类算法不需要强制运行时多态性的成本.如果你想要运行时多态,你可以发送它std::function或其他什么.如果你想要编译时多态,你可以为它提供一个不使用多态调度的类型(aka:大多数函子或函数).
运行时多态性的代价还包括无法内联函数调用.使用适当的函子(甚至函数指针,取决于你的编译器有多好),编译器通常可以根据需要内联函数调用.使用运行时多态性,您不仅要支付运行时调度的成本(可能包括额外的参数转发成本),您还将失去重要的优化机会.
性能!
模板基本功能非常好于std::function模式.我为你做了这个测试:
template <typename F>
void test1(const F &f)
{
for (unsigned long long i = 0; i < 19000000; i++)
f();
}
void test2(function<void()> &f)
{
for (unsigned long long i = 0; i < 19000000; i++)
f();
}
int main()
{
{
LARGE_INTEGER frequency, start, end;
double interval;
QueryPerformanceFrequency(&frequency);
QueryPerformanceCounter(&start);
unsigned long long x = 0;
test1([&x]()
{
x++;
});
QueryPerformanceCounter(&end);
interval = (double) (end.QuadPart - start.QuadPart) / frequency.QuadPart;
cout << "Template mode: " << interval << " " << x << endl;
}
{
LARGE_INTEGER frequency, start, end;
double interval;
QueryPerformanceFrequency(&frequency);
QueryPerformanceCounter(&start);
unsigned long long x = 0;
function<void() > f = [&x]()
{
x++;
};
test2(f);
QueryPerformanceCounter(&end);
interval = (double) (end.QuadPart - start.QuadPart) / frequency.QuadPart;
cout << "std::function mode:" << interval << " " << x << endl;
}
}
Run Code Online (Sandbox Code Playgroud)
模板模式:2.13861e-006
std :: function mode:0.220006
Windows7-O2 Core2 Duo CPU 2.40GHz 上的gcc 4.7.2