我想知道如何做到以下几点
void f(string &&s) {
std::string i(move(s));
/* other stuff */
}
int main() {
std::string s;
bind(f, s)(); // Error.
bind(f, move(s))(); // Error.
bind(f, ref(s))(); // Error.
}
Run Code Online (Sandbox Code Playgroud)
如何传递rvalue引用并将其作为rvalue引用(可能包装)存储在调用包装器中?我知道我可以手动编写一个类似于std::reference_wrapper<>具有转换功能的类T&&,但我宁愿避免这种情况并使用标准技术.
我像AProgrammer推荐的那样实现了它:
template<typename T> struct adv {
T t;
explicit adv(T &&t):t(forward<T>(t)) {}
template<typename ...U> T &&operator()(U &&...) {
return forward<T>(t);
}
};
template<typename T> adv<T> make_adv(T &&t) {
return adv<T>{forward<T>(t)};
}
namespace std {
template<typename T>
struct is_bind_expression< adv<T> > : std::true_type {};
}
Run Code Online (Sandbox Code Playgroud)
现在我可以说 …
请参阅以下代码段.我想使用std::bindfor重载函数foobar.它只调用没有参数的方法.
#include <functional>
#include <iostream>
class Client
{
public :
void foobar(){std::cout << "no argument" << std::endl;}
void foobar(int){std::cout << "int argument" << std::endl;}
void foobar(double){std::cout << "double argument" << std::endl;}
};
int main()
{
Client cl;
//! This works
auto a1 = std::bind(static_cast<void(Client::*)(void)>(&Client::foobar),cl);
a1();
//! This does not
auto a2= [&](int)
{
std::bind(static_cast<void(Client::*)(int)>(&Client::foobar),cl);
};
a2(5);
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我有一个带有几个参数的成员函数.我想将它绑定到特定的对象实例并将其传递给另一个函数.我可以用占位符来做到这一点:
// actualInstance is a MyClass*
auto callback = bind(&MyClass::myFunction, actualInstance, _1, _2, _3);
Run Code Online (Sandbox Code Playgroud)
但这有点笨拙 - 例如,当参数数量发生变化时,我也必须更改所有绑定调用.但另外,键入所有占位符是相当繁琐的,当我真正想要的是方便地创建包含对象引用的"函数指针"时.
所以我希望能够做的是:
auto callback = objectBind(&MyClass::myFunction, actualInstance);
Run Code Online (Sandbox Code Playgroud)
有谁知道这样做的好方法?
c ++中的大部分内容都是0,而不是基于1.出于好奇,为什么占位符1基于?含义_1是第一个参数,而不是_0.
假设这是一个要包装的C函数:
void foo(int(__stdcall *callback)());
Run Code Online (Sandbox Code Playgroud)
C函数指针回调的两个主要缺陷是:
我想知道包装这些函数的最佳方法.第一个对于成员函数回调特别有用,第二个对于使用周围变量的内联定义特别有用,但这些不是唯一用途.
这些特定函数指针的另一个属性是它们需要使用__stdcall调用约定.据我所知,这完全取消了lambda作为一种选择,否则会有点麻烦.我想至少__cdecl也允许这样做.
这是我能够提出的最好的东西,没有东西开始回归依赖于函数指针所没有的支持.它通常在标题中.以下是Coliru的示例.
#include <functional>
//C function in another header I have no control over
extern "C" void foo(int(__stdcall *callback)()) {
callback();
}
namespace detail {
std::function<int()> callback; //pretend extern and defined in cpp
//compatible with the API, but passes work to above variable
extern "C" int __stdcall proxyCallback() { //pretend defined in cpp
//possible additional processing
return callback();
}
}
template<typename F> //takes anything
void wrappedFoo(F …Run Code Online (Sandbox Code Playgroud) 有没有一种方法可以部分绑定可调用对象(例如函数)的前/后n个参数,而无需显式指定其余参数?
std::bind()似乎要求所有的参数都被绑定,那些被留下应该绑定到std::placeholders::_1,_2,_3等.
是否有可能从第一个/最后一个参数开始编写bind_first()/ bind_last()用于部分绑定,并且可以在原始位置以原始顺序自动插入任何剩余未绑定参数的占位符?
我需要将带有已删除的复制构造函数的结构绑定到函数.我已经减少了我想要达到的最小例子:
struct Bar {
int i;
Bar() = default;
Bar(Bar&&) = default;
Bar(const Bar&) = delete;
Bar& operator=(const Bar&) = delete;
};
void foo(Bar b) {
std::cout << b.i << std::endl;
}
int main()
{
Bar b;
b.i = 10;
std::function<void()> a = std::bind(foo, std::move(b)); // ERROR
a();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
从编译器我只会哭泣和咬牙切齿:
test.cpp:22:27: error: no viable conversion from 'typename _Bind_helper<__is_socketlike<void (&)(Bar)>::value, void (&)(Bar), Bar>::type' (aka '_Bind<__func_type (typename decay<Bar>::type)>') to 'std::function<void ()>'
std::function<void()> a = std::bind(foo, std::move(b));
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.1.0/../../../../include/c++/5.1.0/functional:2013:7: note: …Run Code Online (Sandbox Code Playgroud) 我很困惑为什么std::mem_fn需要.
我有一个函数,它接受任何可调用的(lambda,函数指针等),并将它绑定到一个参数.
例如:
template<class T>
void Class::DoBinding(T callable) {
m_callable = std::bind(callable, _1, 4);
}
//somewhere else
Item item;
m_callable(item);
Run Code Online (Sandbox Code Playgroud)
我见过的所有代码示例都是:
//some defined member function
Item::Foo(int n);
DoBinding(std::mem_fn(&Item::Foo));
Run Code Online (Sandbox Code Playgroud)
为什么不能简单地:
DoBinding(&Item::Foo);
Run Code Online (Sandbox Code Playgroud)
似乎后者可以调用而不必使用std :: mem_fn,那么为什么需要呢?
我需要经常做这样的事情:
AsyncOperation * pAsyncOperation = new AsyncOperation();
auto bindOperation = std::bind(&AsyncOperation::operator(), std::ref(*pAsyncOperation));
std::thread thread(bindOperation );
thread.join();
Run Code Online (Sandbox Code Playgroud)
与AsyncOperation任何自定义类实现operator() (也称为函子或函数对象).
是否可以指示std::bind使用std::shared_ptr而不是std::ref?这样可以防止内存泄漏,而不需要保持引用pAsyncOperation,并且会AsyncOperation在线程结束时自动删除,即此异步任务的结束.
编辑:我并不总是有权访问std :: thread,线程库可以是boost :: thread甚至任何其他平台相关的线程.结果,不能访问std :: async.
我的主要问题是在std :: bind中拥有一个占有概念.
我想bind()从派生类到我的基类的函数版本.该功能在基础中标记为受保护.当我这样做时,代码在Clang(Apple LLVM编译器4.1)中快速编译,但在g ++ 4.7.2和Visual Studio 2010中都出错.错误是:"'Base :: foo':不能访问受保护的成员."
这意味着参考的上下文实际上在bind()其中,当然这个函数被视为受保护.但是不应该bind()继承调用函数的上下文 - 在这种情况下,Derived::foo()- 因此将基本方法看作是可访问的?
以下程序说明了该问题.
struct Base
{
protected: virtual void foo() {}
};
struct Derived : public Base
{
protected:
virtual void foo() override
{
Base::foo(); // Legal
auto fn = std::bind( &Derived::foo,
std::placeholders::_1 ); // Legal but unwanted.
fn( this );
auto fn2 = std::bind( &Base::foo,
std::placeholders::_1 ); // ILLEGAL in G++ 4.7.2 and VS2010.
fn2( this );
}
};
Run Code Online (Sandbox Code Playgroud)
为什么行为上的差异?哪个是对的?错误提供编译器有哪些可用的解决方法?
c++ ×10
stdbind ×10
c++11 ×9
boost-bind ×1
callback ×1
currying ×1
lambda ×1
placeholder ×1
protected ×1
shared-ptr ×1
std ×1