是否可以将lambda函数作为函数指针传递?如果是这样,我必须做错了,因为我收到编译错误.
请考虑以下示例
using DecisionFn = bool(*)();
class Decide
{
public:
Decide(DecisionFn dec) : _dec{dec} {}
private:
DecisionFn _dec;
};
int main()
{
int x = 5;
Decide greaterThanThree{ [x](){ return x > 3; } };
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我尝试编译它时,我得到以下编译错误:
In function 'int main()':
17:31: error: the value of 'x' is not usable in a constant expression
16:9: note: 'int x' is not const
17:53: error: no matching function for call to 'Decide::Decide(<brace-enclosed initializer list>)'
17:53: note: candidates are: …Run Code Online (Sandbox Code Playgroud) 由于我上一个最近的问题不幸地措辞并导致解决另一个问题然后我的,我将在这里尝试以明确的方式制定我的实际问题.
在我们开始之前,作为旁注,我正在将Javascript引擎V8集成到我的C++应用程序中.这就是示例中所有类型的来源.这也是我最终需要一个原始函数指针这一事实的原因.但我在下面详细说明.
从类内部我需要将带有capture子句的lambda表达式[=]作为该类型的参数传递std::function给另一个函数,并将其转换为原始函数指针.
在此代码中,InvocationCallback只是具有签名的函数的typedef Handle<Value>(Arguments const &).
typedef Handle<Value> (*InvocationCallback)(Arguments const &);
void Bind(string Name, function<Handle<Value>(Arguments const &)> Function)
{
InvocationCallback* function = Function.target<InvocationCallback>();
}
Run Code Online (Sandbox Code Playgroud)
所有lambda表达式也具有相同的签名.请注意,在此示例中与此Handle<String>兼容Handle<Value>.它也是由Javascript引擎V8提供的.
Bind("name", [=](const Arguments& args) -> Handle<Value>{
Handle<String> result = String::New(Name().c_str());
return result;
});
Run Code Online (Sandbox Code Playgroud)
C++允许我将此lambda传递std::function给上面的函数.但是我猜一个lambda表达式也存储了对它引用的对象的引用.不知何故[=]必须实现指定的访问.这可能是导致std::function原始函数指针失败的原因.
InvocationCallback* function = Function.target<InvocationCallback>();
Run Code Online (Sandbox Code Playgroud)
既没有编译时错误也没有运行时错误,但调试器告诉我它导致空指针.但我需要原始函数指针进行进一步处理.我想我可以std::bind在引用或this-pointer 之后转换lambda .
更新:由于似乎不可能将状态从lambda中取出,这就是我尝试过的.它编译但是function出来是一个空指针.
Bind("name", this, [](Base* object, const Arguments& args) …Run Code Online (Sandbox Code Playgroud) 我有一个函数getTotal:
int getTotal( const HitMap& hitMap, bool( *accept)(int chan) )
Run Code Online (Sandbox Code Playgroud)
其中第二个参数是bool函数,指定应将容器hitMap的哪些成员添加到总数中.
我试着用lambda来调用它.这有效:
auto boxresult =
getTotal(piHits, [](int pmt)->bool
{ return (pmt/100) == 1;} );
Run Code Online (Sandbox Code Playgroud)
但这不是:
int sector = 100;
auto boxresult =
getTotal(piHits, [sector](int pmt)->bool
{ return (pmt/sector) == 1;} );
Run Code Online (Sandbox Code Playgroud)
我收到了错误
cannot convert ‘main(int, char**)::<lambda(int)>’ to ‘bool (*)(int)’
for argument ‘2’ to ‘int getTotal(const HitMap&, bool (*)(int))’
Run Code Online (Sandbox Code Playgroud)
来自我的编译器(GCC 4.6.3).我尝试过[§or],[=sector]但没有任何区别.
我究竟做错了什么?
我的目标是创建一个解决方法,以便我可以在Boost Spirit Qi语义操作中使用C++ 11 lambdas,同时仍然可以访问更多扩展的qi占位符集,例如qi :: _ pass或qi :: _ r1,必须从上下文对象手动提取它们.我希望避免为一些非平凡的解析逻辑编写Phoenix lambdas,更喜欢C++ 11 lambdas中更直接的C++语法和语义.
下面的代码代表了我有一个解决方法的想法.我的想法是使用phoenix :: bind绑定到lambda并将它传递给我需要的特定占位符.但是,我得到了一个极长的模板编译器错误(gcc 4.7.0,Boost 1.54),我没有专业知识来解释.我选择了我认为最相关的部分并将其发布在代码下方.
我想知道我是否可以使用Boost Spirit在此代码中尝试做什么,如果有人能为我解释错误消息并告诉我出了什么问题.
#include <string>
#include <iostream>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace qi = boost::spirit::qi;
namespace spirit = boost::spirit;
namespace phoenix = boost::phoenix;
int main() {
std::string input{"test1 test2 test3 FOO!"};
typedef decltype(input.begin()) StringIter;
qi::rule<StringIter, std::string()> parser =
*(
qi::char_
[
phoenix::bind(
[] (char value) {
std::cerr << value << std::endl;
},
qi::_1
)
]
);
qi::parse(input.begin(), input.end(), parser);
}
Run Code Online (Sandbox Code Playgroud)
(注意:我知道这个代码执行的特定任务对于直接的Phoenix结构会更简单,或者甚至可以通过Boost Spirit更新直接允许单参数C++ …
我正在尝试使用capture [&]传递lambda函数.存储捕获lambda的变量的正确声明是什么?[f2以下]
// Non-capturing
void (*f1)() = [](){ }; // Works
// All by reference
void (*f2)() = [&](){ }; // Syntax Error
Run Code Online (Sandbox Code Playgroud) 如何更改下面的函子以用作 lambda 包装器?
template<typename T>
class F {
T f;
public:
F(T t){
f = t;
}
T& operator()(){
return f;
}
};
int main()
{
int x = 5;
F<int (*)(int, int)> f( [x](int a, int b){return a+b;} );
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译器说
error: no matching function for call to 'F<int (*)(int, int)>::F(main()::<lambda(int, int)>)'
F<int (*)(int, int)> f( [x](int a, int b){return a+b;} );
Run Code Online (Sandbox Code Playgroud) 让这段代码讲述故事(或观看showterm):
#include <iostream>
int foo(bool func (void)) {
int i; for (i = 0; i < 10 && func(); i++);
return i;
}
int main() {
std::cout << foo([] {
return true;
}) << std::endl;
bool a = false;
std::cout << foo([&a] { // error: no matching function for call to 'foo'
return a = !a;
}) << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我希望能够a在我的lambda中捕获,并能够交替返回值.我的实际情况涉及更多,但归结为此.我希望能够使用lambdas,尽管替代方法是使用带有全局变量的普通函数来保持状态.
我正在编译:
clang++ -std=c++11 testcase.cc
Run Code Online (Sandbox Code Playgroud)
我正在使用Apple的LLVM:
Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM …Run Code Online (Sandbox Code Playgroud) 我有一个存储lambda表达式的问题,在类中捕获"this"指针作为参数.我做了这样的typedef:
typedef void(*func)();
Run Code Online (Sandbox Code Playgroud)
以下代码工作正常.
#include <iostream>
using namespace std;
typedef void(*func)();
class A {
public:
func f;
};
class B {
public:
A *a;
B() {
a = new A();
a->f = [](){
printf("Hello!");
};
}
};
int main() {
B *b = new B();
b->a->f();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
还没有捕获但是当我想在lambda中捕获"this"指针时会抛出错误.如何通过捕获来创建typedef?我想做这样的事情:
#include <iostream>
using namespace std;
typedef void(*func)();
class A {
public:
func f;
};
class B {
public:
A *a;
B() {
a = new A();
//There is a problem …Run Code Online (Sandbox Code Playgroud) 以下代码无法编译:
typedef void(*RunnableFun)(int); //pointer-to-function type
void foo(RunnableFun f) {
}
void bar(const std::string& a) {
foo([&](int) -> void { std::cout << a; });
}
Run Code Online (Sandbox Code Playgroud)
和IntelliSense告诉我
Run Code Online (Sandbox Code Playgroud)no suitable conversion function from "lambda []void (int)->void" to "RunnableFun" exists
并且编译器在抱怨
Run Code Online (Sandbox Code Playgroud)'void foo(RunnableFun)' : cannot convert argument 1 from 'bar::<lambda_796873cf40a6be4e411eb9df14f486bf>' to 'RunnableFun'
但以下编译:
typedef void(*RunnableFun)(int); //pointer-to-function type
void foo(RunnableFun f) {
}
void bar(const std::string&) {
// Notice the empty capture list
foo([](int) -> void { std::cout << "dummy"; });
}
Run Code Online (Sandbox Code Playgroud)
如何foo()在第一个代码示例中保留签名但实现我尝试的内容? …