如何在c++ 0x中通过lambda传递
How to pass by lambda in C++0x?
在c++中构造对象避免复制/移动(特别是对于大堆栈分配的对象)的方法似乎是"通过lambda传递"。
请看下面的代码:
#include <iostream>
#define LAMBDA(x) [&] { return x; }
class A
{
public:
A() {};
A(const A&) { std::cout << "Copy "; }
A(A&&) { std::cout << "Move "; }
};
class B1
{
public:
B1(const A& a_) : a(a_) {}
B1(A&& a_) : a(std::move(a_)) {}
A a;
};
class B2
{
public:
B2(const A& a_) : a(a_) {}
B2(A&& a_) : a(std::move(a_)) {}
template <class LAMBDA_T>
B2(LAMBDA_T&& f, decltype(f())* dummy = 0) : a(f()) {}
A a;
};
int main()
{
A a;
std::cout << "B1 b11( a ): ";
B1 b11(a);
std::cout << std::endl;
std::cout << "B2 b12(LAMBDA(a)): ";
B2 b12(LAMBDA(a));
std::cout << std::endl;
std::cout << std::endl;
std::cout << "B1 b21( std::move(a) ): ";
B1 b21(std::move(a));
std::cout << std::endl;
std::cout << "B2 b22(LAMBDA(std::move(a))): ";
B2 b22(LAMBDA(std::move(a)));
std::cout << std::endl;
std::cout << std::endl;
std::cout << "B1 b31(( A() )): ";
B1 b31((A()));
std::cout << std::endl;
std::cout << "B2 b32((LAMBDA(A()))): ";
B2 b32((LAMBDA(A())));
std::cout << std::endl;
std::cout << std::endl;
}
输出如下:
B1 b11( a ): Copy
B2 b12(LAMBDA(a)): Copy
B1 b21( std::move(a) ): Move
B2 b22(LAMBDA(std::move(a))): Move
B1 b31(( A() )): Move
B2 b32((LAMBDA(A()))):
注意,如果参数是一个我认为被称为"右值"的值,则"通过lambda传递"会删除移动。
请注意,"通过lambda传递"方法似乎只在参数为"右值"时有用,但在其他情况下似乎没有害处。
在c++ 0x中是否有方法让函数接受"通过lambda传递"参数,这比客户端必须在lambda函数中包装其参数更好?(而不是定义一个调用该函数的代理宏)。
如果您对模板化构造函数没有意见,那么您不妨使用完全转发,而不是使用lambdas来混淆。
class super_expensive_type {
public:
struct token_t {} static constexpr token = token_t {};
super_expensive_type(token_t);
}
constexpr super_expensive_type::token_t super_expensive_type::token;
class user {
public:
template<typename... Args>
explicit
user(Args&&... args)
: member { std::forward<Args>(args)... }
{}
private:
super_expensive_type member;
};
// ...
// only one construction here
user { super_expensive_type::token };
super_expensive_type moved_from = ...;
// one move
user { std::move(moved_from) };
super_expensive_type copied_from = ...;
// one copy
user { copied_from };
使用lambda不能比这更好,因为必须返回lambda主体中表达式的结果。
你的做法存在一个根本问题。你不能用魔法使一个物体存在。变量必须是:
- 默认构建
- 复制构造
- 移动构建
- 用不同的构造函数构造。
4不在考虑范围内,因为您只定义了前三个。copy和move构造函数都打印东西。因此,可以得出的唯一结论是,如果没有打印任何内容,则对象正在被默认构造。IE:填满nothing.
简而言之,基于lambda的传输机制似乎根本没有传输任何东西。
经过进一步分析,我明白发生了什么。你的lambda实际上并没有通过引用获取值;它是构造一个值。如果展开宏,得到的结果是:
B2 b32(([&] {return A()}));
构造一个临时的;它实际上不需要参考任何东西。所以我不确定你怎么能认为这是"传递"任何东西。你所做的就是创建一个函数来构造一个对象。您可以简单地将B2::a
的构造函数的参数传递给B2
的构造函数,并让它使用它们来创建对象,并且它会给您相同的效果。
没有传递值。你正在创建一个总是创建完全相同对象的函数。这不是很有用。
相关文章:
- 将有状态的 lambda 传递到 C 样式函数中,而无需上下文参数
- 是否可以将带有捕获和参数的 lambda 传递给另一个函数?如果是这样,如何?
- 将带捕获功能的 lambda 传递给模板化函数
- 将带有自动参数的 lambda 传递给另一个函数是否合法
- 如何将通用lambda传递到功能中
- 将lambda传递到lambda回调参数
- 将lambda传递到成员变量的构造函数
- c++:将带有参数的lambda传递给函数
- 应该向C++Lambda传递多少个参数
- 将lambda传递到可变std::函数中时,请键入推导
- 如何将模板 lambda 传递给函数并将其用于不同的类型
- 通过捕获作为另一个lambda的参数将lambda传递
- 如何将C++lambda传递给需要函数指针和上下文的C回调
- 为什么我不能将 lambda 传递给这个采用 std::函数的函数?
- 将lambda传递给模板函数
- 将 lambda 传递到函数模板中
- 将lambda传递给模板类中的方法(头文件/源文件问题)
- 将lambda传递给接受模板化类型函数的函数
- std::function与Lambda传递成员函数
- 将lambda传递给数值库