在C++;17 谷歌在向LAMBDAS传递参数时显示了很多帖子,但是它们都是基于C++ 0x/C++ 11的(例如),我理解这是一个在最近的C++版本中有改进的地方?

在C++;17 谷歌在向LAMBDAS传递参数时显示了很多帖子,但是它们都是基于C++ 0x/C++ 11的(例如),我理解这是一个在最近的C++版本中有改进的地方?,c++,c++17,C++,C++17,我想将非常简单的委托作为方法变量传递给return MyGlobals.GetX(),在我的例子中,MyGlobals是一个全局对象。 i、 e.在伪代码中 //stores and/or calls the lambda myObject.SetXGetter({return MyGlobals.GetX()}); MyObject::SetXGetter(lambda?) { this->mLambda = Lambda; cout << mLambda(); }

我想将非常简单的委托
作为方法变量传递给return MyGlobals.GetX()
,在我的例子中,
MyGlobals
是一个全局对象。 i、 e.在伪代码中

//stores and/or calls the lambda
myObject.SetXGetter({return MyGlobals.GetX()});

MyObject::SetXGetter(lambda?)
{
 this->mLambda = Lambda;
 cout << mLambda();
}
//存储和/或调用lambda
SetXGetter({return MyGlobals.GetX()});
MyObject::SetXGetter(lambda?)
{
这->mLambda=Lambda;

cout在执行过程中只想调用传递的lambda或其他函子的函数可以是函数模板,从而推断函子的类型:

template <typename F>
void use_it(F&& func) {
    do_something_with(func());
}
您的调用缺少lambda表达式所需的初始
[
捕获
]
,即使未捕获任何内容:

myObject.SetXGetter([]{ return MyGlobals.GetX(); });
<> P>我知道这是一个在最近的C++版本中有所改进的地方? 不一般。它已经扩展到一些更复杂的情况,但简单的情况与C++11几乎相同

在C++17中将lambda作为方法参数传递的最简单方法

选项保持不变:

  • 您可以拥有一个模板并按原样传递lambda
  • 或者,您可以将lambda包装在类型擦除包装器中,例如
    std::function
    ,在这种情况下,您可以将其传递到非模板函数中
  • 或者,如果lambda是非捕获的,则可以将其转换为函数指针,该指针也可以传递到非模板中
哪一个最简单可能取决于上下文和个人观点。函数包装器在最广泛的不同情况下工作相同,这是一个简单的选择。函数指针不涉及动态分配,在较低级别上最容易理解。模板不涉及任何形式的包装或转换,但它是一个模板


如果您希望将可调用存储为可修改的成员,则将其存储为lambda不是一个选项。剩下的是函数包装器和函数指针。您仍然可以为函数使用模板,但无论如何都必须立即包装或转换lambda,因此使用模板不会获得太多好处。

对于C++20d以后:

如果不打算存储传递的函数,可以执行以下操作

void use_it(auto func) {
    func();
}
您可以使用概念来约束它,使它除了至少一个可调用的对象之外,什么都不例外

如果要存储参数,很遗憾,您仍然需要像其他答案所建议的那样对其命名,并且它必须能够转换为您指定的类型:

#include <functional>

class MyObject {
public:
    void SetXGetter(auto func) {
        mLambda = std::move(func);
    }

private:
    std::function<int()> mLambda;
};
#包括
类MyObject{
公众:
void SetXGetter(自动函数){
mLambda=std::move(func);
}
私人:
std::函数mLambda;
};

它不就是
myObject.SetXGetter([]{return MyGlobals.GetX();})吗
?你发现了什么?你尝试了什么?你不喜欢的是什么?你在哪里读到C++11改进后的版本,还有什么需要改进?这是一个不清楚的问题。下划线我不知道,我几乎没有使用过lambdas。鉴于我提供了一个确切的示例,它似乎很清楚……我怎么能做到最好简单地声明和调用<代码> SETXGETTER <代码>?我所发现的都是关于旧C++的答案,在这里你使用<代码>函数> <代码>,我为你工作。你是想直接使用lambda还是作为代码> STD:函数< /代码>?eljay:什么对你有用,没有人发布有效代码?我不知道你的问题是什么意思,但是我想要最接近的。对我的伪代码来说,也许你把事情弄糊涂了。从来没有必要有凌乱的包装和/或“临时类型”将lambda传递给函数。顺便说一句,您链接的问题的答案仍然适用。我不理解3个枚举选项和倒数第二个句子。似乎您可以有一个模板方法,将lambda作为
F&&
,但将参数存储在
std::function
中。这些选项适用于哪个选项?@MSalters为了清楚起见,我重新整理了订单。我知道这个问题是关于C++17的,但我对C++20如何改进这一点很好奇,并决定将我的发现作为答案发布。关于编译器资源管理器上的代码:
(auto func)的问题
就是传递一个函子左值可能会产生原始参数类型的一个不必要的副本。
use\u it
只需执行
auto&&func
即可分别处理
const
左值和其他情况,但忽略值类别。但是
SetXGetter
可能会使用完美转发,这在th
auto
键入。或坚持使用
SetXGetter(std::function)
,这会使任何“不可转换”的错误更接近用户的上下文,并自动处理重载/SFINAE,效果更好。@CJCombrink非常有趣,感谢您的发布
void use_it(auto func) {
    func();
}
#include <functional>

class MyObject {
public:
    void SetXGetter(auto func) {
        mLambda = std::move(func);
    }

private:
    std::function<int()> mLambda;
};