是否可以重新绑定 std::function 以指向相同的函数但具有不同的对象实例?
假设我有一个对象,它有一个 std::function 绑定到另一个函数,但如果该对象被复制到另一个实例,我想将 std::function 重新绑定到那个新实例而不是旧实例.
#include "stdafx.h"
#include <iostream>
#include <functional>
class EventHandler
{
public:
int Num;
std::function<int()> OnEvent;
EventHandler (int inNum)
{
Num = inNum;
}
EventHandler (const EventHandler& other)
{
Num = other.Num;
OnEvent = other.OnEvent; //TODO: Need some way to redirect the std::function to the new instance rather than having the delegate point to the original object's handler.
}
int HandleEvent ()
{
return Num;
}
};
int main()
{
EventHandler a(4);
a.OnEvent = …Run Code Online (Sandbox Code Playgroud) 我有一个奇怪的错误,我不太明白,VS2013。这只是我的实际问题的简化,导致了同样的错误。
std::function<bool()> x = (someCondition == true)
? []() { return true; }
: []() { return false; };
Run Code Online (Sandbox Code Playgroud)
VS 编译器错误是:
1>f:\test\cppconsoleapplication\cppconsoleapplication.cpp(497): error C2446: ':' : no conversion from 'main::<lambda_96d01fe3721e46e4e8217a69a07d151b>' to 'main::<lambda_0d38919a9b2aba5caf910d83eac11776>'
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
Run Code Online (Sandbox Code Playgroud)
IntelliSense 甚至想出了这个神秘的错误消息:
IntelliSense: more than one operator "?" matches these operands:
built-in operator "expression ? pointer : pointer"
built-in operator "expression ? pointer : pointer"
built-in operator "expression ? pointer : pointer" …Run Code Online (Sandbox Code Playgroud) 我有一个add使用以下设置的工作虚拟功能:
using Func = std::function<std::vector<unsigned char>()>;
class cfExecutor {
public:
cfExecutor();
virtual ~cfExecutor();
/// Enqueue a function to be executed by this executor. This and all
/// variants must be threadsafe.
virtual void add(Func) = 0;
virtual void add(std::vector<Variant> params, Func callback) = 0;
};
class ManualExecutor : public cfExecutor
{
std::mutex lock_; // avoid multiple entity updating the function container
std::queue<Func> funcs_; // functions queued for running
public:
std::map<int8_t, Func> funcs; // Function container (priority,Func) - added …Run Code Online (Sandbox Code Playgroud) 我有一个需要获取 std::function 类型参数的函数。我还有一个指向对象的抽象类型指针。是否可以仅使用对象来传递方法?
函数签名:
void foo(std::function<bool(int i)>);
Run Code Online (Sandbox Code Playgroud)
课程样本:
class IBase // interface
{
public:
virtual bool sampleMethod(int i) = 0;
};
class Child1 : public IBase // one of the classes that inherit from IBase
{
public:
bool sampleMethod(int i) override;
};
Run Code Online (Sandbox Code Playgroud)
所以有一个指向 Child 类之一的对象的指针:
std::unique_ptr<IBase> ptr;
Run Code Online (Sandbox Code Playgroud)
我想用它来传递sampleMethod作为foo的参数。有什么办法可以使用 std 或 boost 来做到这一点吗?
我有一个 C++ 函数,它接受另外两个函数作为参数:
// ParseResult is a class with a default constructor (no arguments)
ParseResult* bin_op(std::function<ParseResult*()> func_a, std::vector<std::string> ops, std::function<ParseResult*()> func_b);
Run Code Online (Sandbox Code Playgroud)
当我按以下方式调用此函数时:
bin_op(func_1, {"MOD"}, func_2);
// Both func_1 and func_2 are of type ParseResult*, and take in no parameters
Run Code Online (Sandbox Code Playgroud)
编译器抛出这个错误:
no known conversion for argument 1 from '<unresolved overloaded function type>' to 'std::function<ParseResult*()>
Run Code Online (Sandbox Code Playgroud)
我的代码编辑器显示:
no suitable constructor exists to convert from "ParseResult *()" to "std::function<ParseResult *()>"
Run Code Online (Sandbox Code Playgroud)
std::function 包含在代码中。
我该怎么办?我已经尝试使用模板和函数指针解决这个问题,但我没有这样做。
编辑:这是代码库的简化版本:
no known conversion for argument …Run Code Online (Sandbox Code Playgroud) 以下代码有效,但我觉得该行worker([this](int a, long b, int* c){receiver(a, b, c);});有点多余,因为它重复了receiver. 我可以以某种方式直接传递成员函数,而不是传递一个 lambda 函数来调用成员函数吗?
using callback = std::function<void(int, long, int*)>;
void worker(callback c)
{
c(1,2L,(int*)3);
}
class Caller
{
public:
Caller()
{
worker([this](int a, long b, int* c){receiver(a, b, c);});
}
void receiver(int a, long b, int* c)
{
}
};
Run Code Online (Sandbox Code Playgroud) 我想制作一个简单的记录器,它自动运行函数并返回其值。
该类定义为:
template <typename R, typename... Args>
class Logger3
{
Logger3(function<R(Args...)> func,
const string& name):
func{func},
name{name}
{}
R operator() (Args ...args)
{
cout << "Entering " << name << endl;
R result = func(args...);
cout << "Exiting " << name << endl;
return result;
}
function<R(Args...)> func;
string name;
};
Run Code Online (Sandbox Code Playgroud)
我想将以下简单add函数传递给记录器:
int add(int a, int b)
{
cout<<"Add two value"<<endl;
return a+b;
}
Run Code Online (Sandbox Code Playgroud)
通过这样调用它:
auto caller = Logger3<int(int,int)>(add,"test");
Run Code Online (Sandbox Code Playgroud)
但是,它会产生以下错误:
error: function returning a function
133 | Logger3(function<R(Args...)> …Run Code Online (Sandbox Code Playgroud) 以下代码不会编译,因为在编译时没有调用匹配的std :: function构造函数.
template <typename X, typename Y>
Y invoke(std::function<Y(X)> f, X x) {
return f(x);
}
int func(char x) {
return 2 * (x - '0');
}
int main() {
auto val = invoke(func, '2');
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但是,是否可以提供与上述示例中预期相同(或类似)的功能?是否有一种优雅的方式来接受任何可调用的函数:
invoke([](int x) -> int { return x/2; }, 100); //Should return int == 50
bool (*func_ptr)(double) = &someFunction;
invoke(func_ptr, 3.141); //Should return bool
Run Code Online (Sandbox Code Playgroud)
?
这个问题对我来说似乎有点愚蠢,但我找不到任何类似的问题,对不起,这很琐碎
假设我们有一个结构:
struct C {
static void f(int i) { std::cerr << (i + 15) << "\n"; }
static void f(std::string s) { std::cerr << (s + "15") << "\n"; }
};
Run Code Online (Sandbox Code Playgroud)
现在在其他地方:
std::function<void(int)> f1 = C::f; // this does not compile
void (*f2)(std::string s) = C::f; // this compiles just fine
Run Code Online (Sandbox Code Playgroud)
我得到的错误是
错误:请求从“”转换为非标量类型“ std :: function”
在这种情况下有什么方法可以使用std :: function吗?我想念什么?
谢谢
因此,以最简化的形式,我正在进行类似的事情,
template <class T>
bool f(const T &a, const T &b, std::function<bool(const T&, const T&)> func)
{
return func(a,b);
}
template <class T>
bool g(const T &a, const T &b)
{
return true;
}
Run Code Online (Sandbox Code Playgroud)
但是,任何试图调用f(),任何事情,f('a', 'b', g),f(1, 2, g),结果总是在,无论我是否通过变量为const引用或只是简单的值或任何“呼叫到‘F’没有匹配功能”。我以为它无法推断出某些模板,但是我不知道在哪里或为什么。
我承认,我对如何使用函数对象有一个非常脆弱的把握,这样做是否可能?