我正在尝试编写一些代码,通过将函数调用及其参数存储在 lambda/std::function 中,允许我稍后调用函数。理想情况下,参数只会被复制一次(并以其他方式移动),但我可以实现的最小副本数似乎是 2。
//==============================================================================
// INCLUDES
//==============================================================================
#include <iostream>
#include <functional>
#include <memory>
//==============================================================================
// VARIABLES
//==============================================================================
static std::unique_ptr<std::function<void()>> queueFunction;
//==============================================================================
// CLASSES
//==============================================================================
class Test {
public:
Test(int a, int b = 20, int c = 30) : _a(a), _b(b), _c(c) {
std::cout << "Test: Constructor" << std::endl;
}
~Test() {
std::cout << "Test: Destructor" << std::endl;
}
Test(const Test& other) :
_a(other._a)
{
std::cout << "Test: Copy Constructor" << std::endl;
}
Test(Test&& other) :
_a(std::move(other._a))
{
std::cout …Run Code Online (Sandbox Code Playgroud) 跟进我的问题c++ - 使用中间类型时隐式转换如何工作?,从中我了解了1 隐式转换 max的规则,我试图了解涉及函数参数的更高级用例。
假设我有一个函数,它接受另一个函数作为参数。该函数参数可以返回某些内容,也可以不返回任何内容(void)。因此,我想重载函数定义,在一种情况下接受非 void 函数参数,在另一种情况下接受 void 函数参数。
using VoidType = void (string);
using NonVoidType = string (string);
string call(VoidType *fn, string arg) {
cout << "[using void function]" << endl;
fn(arg);
return arg;
}
string call(NonVoidType *fn, string arg) {
cout << "[using non void function]" << endl;
return fn(arg);
}
Run Code Online (Sandbox Code Playgroud)
调用函数时,给定参数具有已知类型,因此重载选择应该很简单,如下所示:
void printVoid(string message) {
cout << message << endl;
}
string printNonVoid(string message) {
cout << message << endl;
return message;
} …Run Code Online (Sandbox Code Playgroud) std::function可以为空,并且可以转换为bool测试它是否有目标。但是,在给它赋值后如何将其设置为 null 呢?
int main()
{
std::function<void()> f = []() { return 4; };
// how to reset to null, to it's initial state when default constructed.
}
Run Code Online (Sandbox Code Playgroud) std :: bind的返回类型是(有意)未指定的.它可以存储在std :: function中.
下面的示例程序显示了如何将std :: bind()返回的临时对象显式转换为std :: function以调用fn1().
如果std :: bind的返回类型是可知的,我可以重载Callback构造函数并且不再需要显式地转换std :: bind临时对象.
有没有办法避免显式演员?
// g++ -std=c++11 test.cxx
#include <functional>
using std::placeholders::_1;
class A
{
public:
void funcA (int x) { }
};
class Callback
{
public:
Callback () = default;
Callback (std::function<void(int)> f) { }
// Wish we knew the return type of std::bind()
// Callback (return_type_of_std_bind f) { }
};
void fn0 (std::function<void(int)> f) { }
void fn1 (Callback cb) { }
int main …Run Code Online (Sandbox Code Playgroud) 我有一个包含各种算法的类:
class Algorithm{
Algorithm()=delete;
public:
template <typename IntegerType>
static IntegerType One(IntegerType a, IntegerType b);
template <typename IntegerType>
static IntegerType Two(IntegerType a, IntegerType b);
template <typename IntegerType>
static IntegerType Three(IntegerType a, IntegerType b);
// ...
};
Run Code Online (Sandbox Code Playgroud)
它们可以通过以下方式调用:
int main(){
Algorithm::One(35,68);
Algorithm::Two(2344,65);
//...
}
Run Code Online (Sandbox Code Playgroud)
现在我想创建一个函数,它将采用任何"算法"函数,并在调用该函数之前和之后执行相同的步骤.
这是我有的:
template <typename IntegerType>
void Run_Algorithm(std::function<IntegerType(IntegerType,IntegerType)>fun, IntegerType a, IntegerType b){
//... stuff ...
fun(a,b);
//... stuff ...
return;
}
Run Code Online (Sandbox Code Playgroud)
当我尝试像这样调用函数时:
Run_Algorithm(Algorithm::One,1,1);
Run Code Online (Sandbox Code Playgroud)
我得到的错误是:
cannot resolve overloaded function ‘One’ based on conversion to type ‘std::function<int(int, int)>’
Run Code Online (Sandbox Code Playgroud)
如何设置通用例程,将所需算法作为参数?
编辑:
此解决方案 …
请考虑以下代码,其中std::function使用三次来捕获一个类的方法:
struct some_expensive_to_copy_class
{
void foo1(int) const { std::cout<<"foo1"<<std::endl; }
void foo2(int) const { std::cout<<"foo2"<<std::endl; }
void foo3(int) const { std::cout<<"foo3"<<std::endl; }
};
struct my_class
{
template<typename C>
auto getFunctions(C const& c)
{
f1 = [c](int i) { return c.foo1(i);};
f2 = [c](int i) { return c.foo2(i);};
f3 = [c](int i) { return c.foo3(i);};
}
std::function<void(int)> f1;
std::function<void(int)> f2;
std::function<void(int)> f3;
};
Run Code Online (Sandbox Code Playgroud)
然而,这将执行该类的三个副本some_expensive_to_copy_class,这是低效的,因为人们可能已经猜到了这个名称.
是否有一个解决方法,只有一个副本?
为了强调它,我对这里使用的方法感兴趣std::function,而不是void-pointers,也没有相应的基于继承的实现.
我为std :: function设置的目标丢失了,我不知道为什么我可能忽略了这个程序中的一些小错误.有人可以帮忙吗
class Test将lambda注册到单例类,但是当尝试调用回调时,std :: function中的目标集将丢失.
#include <iostream>
#include <functional>
using namespace std;
class callback_store final
{
using callback_func_type = std::function<void()>;
public:
static callback_store instance()
{
static callback_store instance;
return instance;
}
void register_callback(callback_func_type func)
{
std::cout << "register_callback() <<<" << std::endl;
m_func = func;
// I am able to call the targets from here.
std::cout << "register_callback() func() " << std::endl;
func();
std::cout << "register_callback() m_func() " << std::endl;
m_func();
// some stats
std::cout << "register_callback() :: " …Run Code Online (Sandbox Code Playgroud) 以下代码给出了分段错误.调试之后,我发现问题可以通过将lambda声明为auto而不是Function来解决.为什么会这样?
#include <functional>
#include <iostream>
#include <vector>
typedef std::vector<double> Vec;
typedef std::function<const Vec&(Vec)> Function;
int main()
{
//Function func = [](const Vec& a)->Vec /*this give me segfault*/
auto func = [](const Vec& a)->Vec /*this work just fine??*/
{
Vec b(2);
b[0] = a[0] + a[1];
b[1] = a[0] - a[0];
return b;
};
Vec b = func(Vec{1,2});
std::cout << b[0] << " " << b[1] << "\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果我可以将它声明为Function,那将是很好的,因为我想将这个lambda表达式传递给其他类.
当func声明为Function时,我所遇到的错误是:
程序接收信号SIGSEGV,分段故障.0x0000000000401896在std :: vector> :: size(this = 0x0)/usr/include/c++/5/bits/stl_vector.h:655 655 …
我正在进行std::vector回调std::function,而我在理解捕获时遇到了一些麻烦.当我尝试使用它们时,它们似乎超出了范围,如果我通过引用捕获它们.如果我按价值捕获,一切正常.
使用这些回调函数的代码需要一定的签名,所以假设我无法修改使用它们的代码,我需要坚持使用捕获变量而不是将事物作为函数参数传递.
当被localVar捕获?是在定义lambda还是调用lambda时?答案是否会根据我是按值还是参考来捕获?
这是我想要了解的一个小例子:
#include <iostream>
#include <functional>
#include <vector>
int main(int argc, char **argv)
{
int n(5);
// make a vector of lambda functions
std::vector<std::function<const int(void)> > fs;
for(size_t i = 0; i < n; ++i){
int localVar = i;
auto my_lambda = [&localVar]()->int // change &localVar to localVar and it works
{
return localVar+100;
};
fs.push_back(my_lambda);
}
// use the vector of lambda functions
for(size_t i = 0; i < n; …Run Code Online (Sandbox Code Playgroud) 我希望有一个function_list <>模板类,其中包含std :: function <>值的向量。关键是我想用声明单个std :: function <>的相同形式声明列表。例如
function_list<void()> functions; // list of std::functions that take and return void
Run Code Online (Sandbox Code Playgroud)
下面是我尝试实现的方法。我尝试遵循标准库的函数头文件中std :: function <>模板所使用的相同语法。
#include <functional>
#include <vector>
#include <iostream>
template<class _R, class... _Args>
class function_list<_R(_Args...)>
{
public:
std::vector<std::function<_R(_Args...)>> functions;
function_list& operator+=(std::function<_R(_Args...)> f) { functions.push_back(f); return *this; }
void call_all(_Args... args) { for (auto& f : functions) { f(args...); } }
};
int main()
{
function_list<void()> fl;
fl += []() { std::cout << "Hello, World!" << std::endl; };
fl …Run Code Online (Sandbox Code Playgroud) c++ ×10
std-function ×10
c++11 ×6
lambda ×4
templates ×2
ambiguous ×1
callable ×1
delegates ×1
overloading ×1
parameters ×1
stdbind ×1
stl ×1
type-erasure ×1