I类继承的构造函数需要传入一个非平凡的对象。与此类似:
MyFoo::MyFoo() : SomeBase( complexstuff )
{
return;
}
complexstuff
与MyFoo
几乎没有关系,因此我不想将其传入。
我没有写一些返回complexstuff
的1-off临时函数,而是使用了lambda。我花了几分钟才弄明白的是我必须调用 lambda。所以我的代码现在看起来像这样:
MyFoo::MyFoo() : SomeBase(
[]()
{
/* blah blah do stuff with complexstuff */
return complexstuff;
} () )
{
return;
}
如果你没有抓住它,那就很微妙了。但是在lambda体之后,我不得不把()
告诉编译器立即"运行" lambda。在弄清楚我做错了什么之后才有意义。否则,如果没有()
来调用lambda,gcc就会说出类似的内容:
error: no matching function for call to 'SomeBase(<lambda()>)'
但现在我有想法 - 我这样做了吗?在C ++ 11或C ++ 14中是否有更好的方法告诉编译器我希望它立即调用我写的lambda?或者添加一个空的()
,就像我按照通常的方式做到这一点?
答案 0 :(得分:12)
但现在我想到了 - 我是否正确地做到了这一点?
是的,你做到了。
在C ++ 11或C ++ 14中是否有更好的方法告诉编译器我希望它立即调用我编写的lambda?
不是我知道的。 lambda也只是一个函数对象,所以你需要让()
来调用它,没有办法解决它(当然除了一些调用lambda的函数,如{{ 1}})。
如果需要,可以在捕获列表后删除std::invoke
,因为lambda不接受任何参数。
或者添加一个空
()
,就像我按照通常的方式做到这一点?
是的,这是最短的路。如前所述,()
也会起作用,但需要更多输入。我会说用std::invoke
进行直接调用是通常的做法。
答案 1 :(得分:4)
没有办法告诉编译器立即调用lambda。最简单的课程(在复杂性和打字字符数量方面)就是你已经做过的。对于那些使用过具有闭包语言的人来说,这也非常惯用(我在这里思考JavaScript)。
如果您想避免语法,请修改SomeBase
或complexstuff
以执行可调用。
如果您想要的只是用于调用lambda的语法糖,您可以随时执行像Alexandrescu的SCOPE_GUARD那样的操作,并滥用运算符重载:
#include <iostream>
constexpr enum {} invoke{};
template<class Callable>
auto operator+(decltype(invoke) const&, Callable c) -> decltype(c()) {
return c();
}
int main() {
invoke + []() {
std::cout << "called";
};
}
但我不会。发明自己的DSL只会让你的代码更糟糕。坚持使用简单语言结构的习语。
答案 2 :(得分:4)
在C ++ 17中,您可以使用std::invoke
。这与你做的完全相同,但也许你会发现这个更清楚。
#include <iostream>
#include <functional>
void foo(int i)
{
std::cout << i << '\n';
}
int main()
{
foo( std::invoke( []() { return 1; } ) );
}
答案 3 :(得分:2)
有没有更好的方式
您还可以考虑使用构建complexstuff
的私有静态成员函数,例如
class MyFoo : public Base {
private:
static SomeComplexType compute_complex_stuff() {
SomeComplexType complexstuff;
/*compute the complexstuff */
return complexstuff;
};
public:
MyFoo() : Base(compute_complex_stuff()) {};
};
我不知道它是否比定义一个lambda表达式并立即应用它更好;这是恕我直言的品味;对于一个 short lambda体,我更喜欢立即应用一个lambda表达式(但是在这种情况下,某些编译器可能会创建临时闭包,所以没有优化它可能会更慢;我期望大多数C ++ 11编译器能够进行优化。)
BTW,GCC为您的目的提供statement expression语言扩展(Clang也理解)。有了它,你可以写
MyFoo::MyFoo : Base (({
SomeComplexType complexstuff;
/*compute the complexstuff */
return complexstuff;
}) {};