我可以轻松地将成员函数绑定到a std::function带有capture子句的lambda表达式.
class Class
{
Class()
{
Register([=](int n){ Function(n); });
}
void Register(std::function<void(int)> Callback)
{
}
void Function(int Number)
{
}
};
Run Code Online (Sandbox Code Playgroud)
但我想直接绑定它们,如下所示.
// ...
Register(&Class::Function);
// ...
Run Code Online (Sandbox Code Playgroud)
我认为根据C++ 11标准,这应该得到支持.但是,在Visual Studio 11中,我收到了这些编译器错误.
错误C2440:'换行':无法从'int'转换为'Class*'
错误C2647:'.*':无法在'int'上取消引用'void(__thiscall Class ::*)(int)'
有没有办法将std :: bind绑定到std :: weak_ptr?我想存储一个"弱函数"回调,当被调用者被销毁时,它会自动"断开连接".
我知道如何使用shared_ptr创建一个std :: function:
std::function<void()> MyClass::GetCallback()
{
return std::function<void()>(std::bind(&MyClass::CallbackFunc, shared_from_this()));
}
Run Code Online (Sandbox Code Playgroud)
但是返回的std :: function使我的对象永远保持活着.所以我想将它绑定到weak_ptr:
std::function<void()> MyClass::GetCallback()
{
std::weak_ptr<MyClass> thisWeakPtr(shared_from_this());
return std::function<void()>(std::bind(&MyClass::CallbackFunc, thisWeakPtr));
}
Run Code Online (Sandbox Code Playgroud)
但那不编译.(std :: bind将不接受weak_ptr!)有没有办法绑定到weak_ptr?
我已经找到了关于这个的讨论(见下文),但似乎没有标准的实现.存储"弱功能"的最佳解决方案是什么,特别是如果Boost不可用?
讨论/研究(所有这些都使用Boost并且没有标准化):
我在理解函数类型时遇到问题(它们看起来像是a的Signature模板参数std::function):
typedef int Signature(int); // the signature in question
typedef std::function<int(int)> std_fun_1;
typedef std::function<Signature> std_fun_2;
static_assert(std::is_same<std_fun_1, std_fun_2>::value,
"They are the same, cool.");
int square(int x) { return x*x; }
Signature* pf = square; // pf is a function pointer, easy
Signature f; // but what the hell is this?
f(42); // this compiles but doesn't link
Run Code Online (Sandbox Code Playgroud)
变量f无法分配,但可以调用.奇怪的.那有什么好处呢?
现在,如果我对typedef进行const限定,我仍然可以使用它来构建更多类型,但显然没有别的:
typedef int ConstSig(int) const;
typedef std::function<int(int) const> std_fun_3;
typedef std::function<ConstSig> std_fun_4;
static_assert(std::is_same<std_fun_3, std_fun_4>::value,
"Also the same, …Run Code Online (Sandbox Code Playgroud) 我有必要使用,std::function但我不知道std::function语法是什么意思.
使用std :: function的目标是什么?它是一个指向函数的指针吗?
我发现在下面有一个简洁的语法并不简单:
std::function<int(float, bool)>
Run Code Online (Sandbox Code Playgroud)
如果我将该函数声明为:
template <class RetType, class... Args>
class function {};
Run Code Online (Sandbox Code Playgroud)
定义函数的模板类型是一种普通的语法:
function<int,float,bool> f;
Run Code Online (Sandbox Code Playgroud)
但它适用于部分模板专业化的奇怪技巧
template <class> class function; // #1
template <class RV, class... Args>
class function<RV(Args...)> {} // #2
Run Code Online (Sandbox Code Playgroud)
这是为什么?为什么我需要为模板提供一个空类型参数(#1),否则它将无法编译
以下片段:
#include <functional>
struct X {
X(std::function<double(double)> fn); // (1)
X(double, double); // (2)
template <class T>
auto operator()(T const& t) const { // (3)
return t.foo();
}
};
int main() {
double a, b;
auto x = X(a, b);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
... 当使用- 在OSX和godbolt.org上测试时,无法使用clang(4.0.1)和g++(6.3,7.2)-std=c++14进行编译.
但如果符合以下情况,它编译没有问
(1);double)(3);-> decltype(t.foo()))(3);-std=c++1z(感谢@bolov).也许有一些明显我在这里失踪的东西......这段代码有什么问题吗?这是一个错误吗?
c++ function-object std-function return-type-deduction c++14
我知道以下代码无法编译。
void baz(int i) { }
void baz() { }
class Bar
{
std::function<void()> bazFn;
public:
Bar(std::function<void()> fun = baz) : bazFn(fun){}
};
int main(int argc, char **argv)
{
Bar b;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
因为std::function据说不考虑重载决议,正如我在另一篇文章中读到的。
我不完全理解迫使这种解决方案的技术限制。
我在 cppreference 上阅读了翻译和模板的阶段,但我想不出任何我找不到反例的推理。向半个外行(C++ 的新手)解释一下,是什么以及在哪个翻译阶段导致上述无法编译?
如果你有一个模板化的类或模板化的函数(或两者的组合),你如何绑定该函数,(保留模板类型参数)?
我在下面的帖子中给出了一些关于基本语法的帮助,用显式模板类型参数绑定到函数,但是在这个过程中失去了提供模板类型参数的能力.
是否有可能使其工作,以便仍然可以提供未来调用的模板类型参数?
清理过这段代码很多,但显然无法编译,因为我找不到正确的语法,(有没有办法做到这一点)?
删除了"向量"要求以简化此操作:
谢谢您的帮助!
#include <functional>
#include <vector>
#include <string>
/***************************************/
template <typename CommandTemplateType>
class Storage
{
public:
// No idea how to define this vector to allow Template Parameters
// static std::vector<std::function<void<ParameterTemplateType>
// (std::shared_ptr<ParameterTemplateType>)>> Functions;
// I really don't need the collection, a single member would kick start my research:
static std::function<void<ParameterTemplateType>(std::shared_ptr<ParameterTemplateType>)> Function;
template <typename ParameterTemplateType>
static void Execute(ParameterTemplateType parameter)
{
// Look up index, or loop through all..
// I am trying to invoke the bound …Run Code Online (Sandbox Code Playgroud) 我正在更新一些旧代码,以使用C++ 11功能代替boost等价物.然而,并非所有东西都是简单的命名空间替换,如无序容器和智能指针.
例如boost::function有方法empty(),clear()但std::function没有.
有一个已operator()定义的std::function,我一直在使用替换empty()引用,但我应该用什么来替换clear()引用?
我已经考虑过使用std::function赋值运算符并指定nullptr清除它,但我担心可能会产生无意识的副作用,不仅清除底层函数,还会使对象无法使用.
显然,更好的解决方案是任何可重用的成员函数对象的默认初始化,这种方式总是有一个有效的回调,可以简单地用用户提供的回调更新,但我只是想直接替换以前的用法而不是代码审查.
以下代码无法编译:
#include <functional>
struct X
{
std::function<X()> _gen;
};
int main()
{
X x;
x._gen = [] { return X(); }; //this line is causing problem!
}
Run Code Online (Sandbox Code Playgroud)
我不明白为什么分配x._gen导致问题.无论GCC和铛是给类似的错误消息.有人可以解释一下吗?
In file included from main.cpp:1:0:
/usr/include/c++/4.8/functional: In instantiation of ‘std::function<_Res(_ArgTypes ...)>::_Requires<std::function<_Res(_ArgTypes ...)>::_CheckResult<std::function<_Res(_ArgTypes ...)>::_Invoke<_Functor>, _Res>, std::function<_Res(_ArgTypes ...)>&> std::function<_Res(_ArgTypes ...)>::operator=(_Functor&&) [with _Functor = main()::__lambda0; _Res = X; _ArgTypes = {}; std::function<_Res(_ArgTypes ...)>::_Requires<std::function<_Res(_ArgTypes ...)>::_CheckResult<std::function<_Res(_ArgTypes ...)>::_Invoke<_Functor>, _Res>, std::function<_Res(_ArgTypes ...)>&> = std::function<X()>&]’:
main.cpp:11:12: required from here
/usr/include/c++/4.8/functional:2333:4: error: …Run Code Online (Sandbox Code Playgroud)