感谢C++ 11,我们收到了std::functionfunctor包装器系列.不幸的是,我一直只听到关于这些新增内容的不好的事情.最受欢迎的是它们非常慢.我对它进行了测试,与模板相比,它们真的很糟糕.
#include <iostream>
#include <functional>
#include <string>
#include <chrono>
template <typename F>
float calc1(F f) { return -1.0f * f(3.3f) + 666.0f; }
float calc2(std::function<float(float)> f) { return -1.0f * f(3.3f) + 666.0f; }
int main() {
using namespace std::chrono;
const auto tp1 = system_clock::now();
for (int i = 0; i < 1e8; ++i) {
calc1([](float arg){ return arg * 0.5f; });
}
const auto tp2 = high_resolution_clock::now();
const auto d = duration_cast<milliseconds>(tp2 - tp1);
std::cout << …Run Code Online (Sandbox Code Playgroud) 我知道什么是仿函数以及何时将它们与stl algos一起使用.但不明白他在这个主题中的意思:
任何人都可以解释什么是什么std,什么std::bind时候应该使用,新手的一些例子?
我想知道如何正确检查是否std::function为空.考虑这个例子:
class Test {
std::function<void(int a)> eventFunc;
void registerEvent(std::function<void(int a)> e) {
eventFunc = e;
}
void doSomething() {
...
eventFunc(42);
}
};
Run Code Online (Sandbox Code Playgroud)
这段代码在MSVC中编译得很好,但如果我在doSomething()没有初始化的情况下调用eventFunc代码,那么显然会崩溃.这是预期的,但我想知道它的价值是eventFunc多少?调试器说'empty'.所以我使用简单的if语句修复了它:
void doSomething() {
...
if (eventFunc) {
eventFunc(42);
}
}
Run Code Online (Sandbox Code Playgroud)
这有效,但我仍然想知道非初始化的价值是std::function多少?我想写,if (eventFunc != nullptr)但std::function(显然)不是指针.
为什么纯净如果有效?它背后的魔力是什么?而且,这是检查它的正确方法吗?
我想std::set用自定义比较函数创建一个.我可以将它定义为一个类operator(),但我想享受定义使用它的lambda的能力,所以我决定在具有std::setas成员的类的构造函数的初始化列表中定义lambda函数.但我无法得到lambda的类型.在我继续之前,这是一个例子:
class Foo
{
private:
std::set<int, /*???*/> numbers;
public:
Foo () : numbers ([](int x, int y)
{
return x < y;
})
{
}
};
Run Code Online (Sandbox Code Playgroud)
我在搜索后找到了两个解决方案:一个,使用std::function.只需设置比较函数类型std::function<bool (int, int)>,就像我一样传递lambda.第二个解决方案是编写一个make_set函数,就像std::make_pair.
解决方案1:
class Foo
{
private:
std::set<int, std::function<bool (int, int)> numbers;
public:
Foo () : numbers ([](int x, int y)
{
return x < y;
})
{
}
};
Run Code Online (Sandbox Code Playgroud)
解决方案2:
template <class Key, class Compare>
std::set<Key, Compare> make_set (Compare compare) …Run Code Online (Sandbox Code Playgroud) 我已经开始使用C++进行函数式编程的基础知识.我正在尝试创建一个f(a)(b)(c)将返回的函数a + b + c.我成功实现了f(a)(b)返回a + b 的函数.这是它的代码:
std::function<double(double)> plus2(double a){
return[a](double b){return a + b; };
}
Run Code Online (Sandbox Code Playgroud)
我只是无法弄清楚如何实现f(a)(b)(c)我之前声明应该返回的功能a + b + c.
在我的C++应用程序中(使用Visual Studio 2010),我需要存储一个std :: function,如下所示:
class MyClass
{
public:
typedef std::function<int(int)> MyFunction;
MyClass (Myfunction &myFunction);
private:
MyFunction m_myFunction; // Should I use this one?
MyFunction &m_myFunction; // Or should I use this one?
};
Run Code Online (Sandbox Code Playgroud)
如您所见,我在构造函数中添加了函数参数作为引用.
但是,在我的班级中存储该功能的最佳方法是什么?
我的直觉是说存储引用是安全的(甚至是const引用).我希望编译器在编译时为lambda生成代码,并在应用程序运行时将此可执行代码保存在"虚拟"内存中.因此,可执行代码永远不会被"删除",我可以安全地存储对它的引用.但这是真的吗?
鉴于以下代码,模糊性背后的原因是什么?我可以绕过它还是我必须保持(讨厌的)显式演员?
#include <functional>
using namespace std;
int a(const function<int ()>& f)
{
return f();
}
int a(const function<int (int)>& f)
{
return f(0);
}
int x() { return 22; }
int y(int) { return 44; }
int main()
{
a(x); // Call is ambiguous.
a(y); // Call is ambiguous.
a((function<int ()>)x); // Works.
a((function<int (int)>)y); // Works.
return 0;
}
Run Code Online (Sandbox Code Playgroud)
有趣的是,如果我a()用function<int ()>参数注释掉函数并a(x)在我的main中调用,则编译正确失败,因为它们之间的类型不匹配x和function<int (int)>唯一a()可用函数的参数.如果编译器在这种情况下失败,为什么在存在这两个a()函数时会有任何歧义?
我试过VS2010和g ++ v.4.5.两者都给我完全相同的歧义.
从cppreference,我发现:
类模板std :: function是一个通用的多态函数包装器.std :: function的实例可以存储,复制和调用任何Callable目标 - 函数,lambda表达式,绑定表达式或其他函数对象,以及指向成员函数和指向数据成员的指针.
我不明白为什么一个std::function应该能够存储这样的指针,我以前从未听说过这个功能.
它是否真的可能,我错过了某些内容或文档中的错误?
operator()在这种情况下应该怎么做?
从文档中可以看出:
使用参数args调用存储的可调用函数目标.
无论如何,这里没有存储的可调用函数目标.我错了吗?
说实话,我甚至无法弄清楚这个函数的正确语法是什么,否则我会写一个例子来测试它.
如何使用以下模板来定义指向数据成员的指针?
template< class R, class... Args >
class function<R(Args...)>
Run Code Online (Sandbox Code Playgroud) 我试图理解为什么std::function无法区分重载函数.
#include <functional>
void add(int,int){}
class A {};
void add (A, A){}
int main(){
std::function <void(int, int)> func = add;
}
Run Code Online (Sandbox Code Playgroud)
在上面显示的代码中,function<void(int, int)>只能匹配其中一个功能,但它会失败.为什么会这样?我知道我可以通过使用lambda或函数指针到实际函数然后将函数指针存储在函数中来解决这个问题.但为什么这会失败?关于我想要选择哪个功能的上下文不清楚吗?请帮助我理解为什么这会失败,因为我无法理解为什么在这种情况下模板匹配失败.
我得到的编译错误如下:
test.cpp:10:33: error: no viable conversion from '<overloaded function type>' to
'std::function<void (int, int)>'
std::function <void(int, int)> func = add;
^ ~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__functional_03:1266:31: note:
candidate constructor not viable: no overload of 'add' matching
'std::__1::nullptr_t' for 1st argument
_LIBCPP_INLINE_VISIBILITY function(nullptr_t) : __f_(0) {}
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__functional_03:1267:5: note:
candidate constructor not viable: no overload of 'add' …Run Code Online (Sandbox Code Playgroud) 我怎样才能比较两个C++ 11个std::functions的operator==,并返回true如果两个所述functions请参阅同一个函数指针?
c++ ×10
std-function ×10
c++11 ×9
lambda ×2
stl ×2
currying ×1
data-members ×1
stdbind ×1
templates ×1