我想将函数的赋值封装到std :: function中.我没有传递std :: function或指向std :: function的指针,而是传递从公共抽象类Slot继承的函子(即这些插槽提供了额外的功能).
我在不同的形状偶然发现了这个问题在这里.例如,使用通用槽指针代替std:函数的动机是仿函数的生命周期管理.
以下代码说明了该问题.请参阅assignFunctorPtr(...)方法.
#include <iostream>
#include <functional>
template<class FunSig>
class Slot;
template<class R>
class Slot<R()>
{
public:
typedef R Ret_type;
public:
virtual ~Slot() {}
virtual Ret_type operator()() = 0;
};
template<class R, class A1>
class Slot<R(A1)>
{
public:
typedef R Ret_type;
typedef A1 Arg1_type;
public:
virtual ~Slot() {}
virtual Ret_type operator()(Arg1_type) = 0;
};
class TestSlot: public Slot<void (float &)>
{
public:
void operator()(float& f)
{ std::cout << f ;}
};
template<class …Run Code Online (Sandbox Code Playgroud) 我正在使用C++ 11库中的标准函数包装器,我看到它的布尔运算符有一些奇怪的行为.如果我创建一个std::function对象,则布尔运算符返回false.如果我分配nullptr给对象并再次检查,则仍然如此.当我为它分配一个我已经转换为函数指针的void指针时出现问题.考虑以下程序:
#include <functional>
#include <iostream>
void* Test() {
return nullptr;
}
int main(int argc, char* argv[]) {
std::function<void()> foo;
std::cout << !!foo << std::endl;
foo = nullptr;
std::cout << !!foo << std::endl;
foo = reinterpret_cast<void(*)()>(Test());
std::cout << !!foo << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我期望作为输出,0 0 0但结果是0 0 1(见演示).任何人都可以解释为什么布尔运算符在包含空的,不可调用的函数指针时返回true?并请还提到的解决方法,检查nullptr在std::function
注意:我已经尝试检查目标是否为null(with foo.target<void*>() == nullptr)而不是使用布尔运算符,但似乎无论函数对象包含什么,目标始终为null(即使函数对象完全没有问题)被称为).
有什么不同吗?
哪种"保存/转移"功能最好?
function<void(int)> fcn =
[](int par) {std::cout<<"fcn: "<<par<<std::endl; };
void(*fcn_a)(int) =
[](int par) {std::cout<<"fcn_a: "<<par<<std::endl; };
fcn(12);
fcn_a(12);
Run Code Online (Sandbox Code Playgroud)尝试将重载的静态函数传递给时,我收到"未解析的重载函数类型"错误std::function.
我知道类似的问题,比如这个和这个.但是,即使那里的答案用于将正确函数的地址转换为函数指针,它们也会失败std::function.这是我的MWE:
#include <string>
#include <iostream>
#include <functional>
struct ClassA {
static std::string DoCompress(const std::string& s) { return s; }
static std::string DoCompress(const char* c, size_t s) { return std::string(c, s); }
};
void hello(std::function<std::string(const char*, size_t)> f) {
std::string h = "hello";
std::cout << f(h.data(), h.size()) << std::endl;
}
int main(int argc, char* argv[]) {
std::string (*fff) (const char*, size_t) = &ClassA::DoCompress;
hello(fff);
hello(static_cast<std::string(const char*, size_t)>(&ClassA::DoCompress));
}
Run Code Online (Sandbox Code Playgroud)
有人可以解释为什么static_cast隐含的那个不起作用?
读取用于C++ 17的建议有关删除标准的一些过时,旧的和未使用的部分(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4190.htm)我找到D.9部分有点奇怪:
D.9"粘合剂"[depr.lib.binders]
这定义了bind1st()/ bind2nd(),它们被bind()严格取代.(在将来,我会认为,bind()的本身已被lambda表达式,尤其是通用的Lambda表达式取代,所以绑定()应该被废弃,但不是此提案的一部分.)
我没有得到的是关于bind()自己被lambdas取代的评论.
如果我有课:
class A
{
public:
void f(int a){}
void f(int a, int b){}
}
Run Code Online (Sandbox Code Playgroud)
而且我想将一个函数指针传递A::f给某个函数,someFunction以便这个函数可以在实例化的对象上调用它A,我声明someFunction:
void someFunction(const std::function<void(int, int)>&);
Run Code Online (Sandbox Code Playgroud)
并称之为:
A a;
someFunction(std::bind(static_cast<void (A::*)(int, int)> (&A::f),
std::ref(a),
std::placeholders::_1,
std::placeholders::_2));
Run Code Online (Sandbox Code Playgroud)
如何使用lambda实现相同的功能?真的没有什么bind()可以做的,用lambda无法做到吗?
我们有一个遗留系统,它集中使用boost :: function,现在它决定转向更新的现代C++标准.假设我们有这样的遗留函数:
void someFunction(boost::function<void(int)>);
Run Code Online (Sandbox Code Playgroud)
直接传入C++ 11函数是否安全?
//calling site, new C++11 code
std::function<void(int)> func = [](int x){
//some implementation
}
someFunction(func); //will this always work?
Run Code Online (Sandbox Code Playgroud)
boost :: function是否也能优雅地处理标准C++ 11 lambda?
// will this also work?
someFunction([](int x)->void{
//some implementation
});
Run Code Online (Sandbox Code Playgroud) 从这里开始,在我看来,std::function没有function_type或等效的成员类型可以导出用于初始化它的实际类型.
它result_type,argument_type以及first_argument_type和second_argument_type,但没有喜欢的类型如上所述.
为什么它不提供这种类型的接口?
肯定有一个很好的理由,但我无法弄清楚是什么原因,所以我很想知道它是什么.
因为我知道第一个问题就是为什么你需要它,好吧,想象一下,我想做一些事情,比如std::is_same<F1::function_type, F2::function_type>::value在sfinae评估中检查它们的基础类型是否相同,只要它们包含不同的函数就可以了.迹象是一样的.
我承认这没有多大意义,说实话,这个问题只是为了好奇.
编辑
正如@Brian在他的回答评论中指出的那样,我在写作时误用了初始化这个词:
导出用于初始化它的实际类型
我感兴趣的是模板参数.
作为一个例子,对于std::function<void(S&, int)>(在哪里S是结构),function_type将是void(S&, int).
要创建std :: function,我就是这样做的: -
std::function<void(int,int,int)> f=
std::bind(&B::fb,this,
std::placeholders::_1,
std::placeholders::_2,
std::placeholders::_3
);
void B::fb(int x,int k,int j){} //example
Run Code Online (Sandbox Code Playgroud)
很明显,B::fb接收三个参数.
为了提高可读性和可维护性,我希望我可以这样称呼: -
std::function<void(int,int,int)> f=std::bind(&B::fb,this); //omit _1 _2 _3
Run Code Online (Sandbox Code Playgroud)
问题
C++中是否有任何功能可以省略占位符?
它应该自动在命令中调用_1,_2,....
我用谷歌搜索"省略占位符c ++"但没有发现任何线索.
是否有可能将std::function自己内部的一个替换为另一个std::function?
以下代码无法编译:
#include <iostream>
#include <functional>
int main()
{
std::function<void()> func = []()
{
std::cout << "a\n";
*this = std::move([]() { std::cout << "b\n"; });
};
func();
func();
func();
}
Run Code Online (Sandbox Code Playgroud)
可以对其进行修改以进行编译吗?
现在的错误消息是:此lambda函数未捕获“ this” -我完全理解。我不知道,但是,我怎么能抓住func的this终场。我想,这甚至不是std::function lambda里面了吗?如何才能做到这一点?
背景:我要实现的目标如下:在给定的第一次调用中std::function,我想做一些初始化工作,然后用优化的函数替换原始函数。我想为我的功能用户透明地实现这一目标。
上面的示例的预期输出为:
a
b
b
这是我面临的问题:我在一个类中有一个重载函数,并且我想将其重载之一作为参数传递。但是这样做时,出现以下错误:
"no suitable constructor exists to convert from <unknown-type> to std::function<...>"
Run Code Online (Sandbox Code Playgroud)
这是一个代码示例来说明这一点:
#include <functional>
#include <string>
class Foo
{
private:
int val1 , val2;
};
class Bar
{
public:
void function ( ) {
//do stuff;
Foo f;
function ( f );
}
void function ( const Foo& f ) {
//do stuff
}
private:
//random attribute
std::string str;
};
void otherFunction ( std::function<void ( Bar& , const Foo& ) > function ) {
Bar b;
Foo f;
function(b,f);
} …Run Code Online (Sandbox Code Playgroud)