我的lambda在复制构建期间没有正确转换捕获的"this"
My lambda does not correctly convert the captured 'this' during copy construction
我已经将问题缩小到了这个
#include <iostream>
#include <functional>
struct Foo {
std::function<Foo*()> lambda;
Foo()
:lambda([this](){return this;})
{}
};
int main(){
Foo a;
Foo b = a;
std::cout << &a << " " << a.lambda() << std::endl;
std::cout << &b << " " << b.lambda() << std::endl;
}
输出为
0x7ffd9128b8a0 0x7ffd9128b8a0
0x7ffd9128b880 0x7ffd9128b8a0
我最初期望this
总是指向拥有lambda的实例。但是,我忘记了复制构造。在这种情况下,Lambda捕获了this
,然后固定,无论复制Lambda多少次,都指向this
的原始值。
是否有一种方法来修复此操作,以便lambda始终对其拥有对象this
的参考,即使在拥有对象的复制构造下也是如此。
听起来您需要提供自己的特殊会员功能,不是吗?例如,对于复制构造函数:
Foo(const Foo& other)
:lambda([this](){return this;})
{}
,而@lubgr回答了我问的问题,我认为值得注意的是我确切的问题的其他解决方案。这个问题源于建立班级来封装成员的懒惰初始化。我最初的尝试是
template <typename T>
class Lazy {
mutable boost::once_flag _once;
mutable boost::optional<T> _data;
std::function<T()> _factory;
void Init() const { boost::call_once([&] { _data = _factory(); }, _once); }
public:
explicit Lazy(std::function<T()> factory):_once(BOOST_ONCE_INIT),_factory(factory){}
T& Value() {
Init();
return *_data;
}
};
可以像
一样使用class Foo {
int _a;
Lazy<int> _val;
Foo(a):_a(a):_val([this](){return this->_a+1;}){}
}
Foo f(10);
int val = f._val.Value();
,但我在问题中提出的问题与this
是一个循环参考,无法保留用于复制构造。该解决方案不是创建自定义复制构造函数,也可能是移动构造函数,而是要修复懒惰实现类,以便我们可以将ARG传递给工厂。
懒惰的新实施是
template <typename T, typename TThis>
class LazyMember {
mutable boost::once_flag _once;
mutable boost::optional<T> _data;
typedef std::function<T(TThis const*)> FactoryFn;
FactoryFn _factory;
void Init(TThis const * arg0) const { boost::call_once([&] { _data = _factory(arg0); }, _once); }
public:
explicit LazyMember(FactoryFn factory):_once(BOOST_ONCE_INIT),_factory(factory){}
T& Value(TThis const * arg0) { Init(arg0); return *_data; }
T const & Value(TThis const * arg0) const { Init(arg0); return *_data; }
};
用作
class Foo {
int _a;
Lazy<int> _val;
Foo(a):_a(a):_val([](Foo const * _this){return _this->_a+1;}){}
}
Foo f(10);
int val = f._val.Value(&f);
这没有循环参考问题,因此不需要自定义复制/移动构造函数。
相关文章:
- 为什么我需要在转换构造函数上引用 this->?
- 将"this"从父类方法转换为子类方法是一种好的做法吗?
- 我的lambda在复制构建期间没有正确转换捕获的"this"
- 编译错误:2 个重载没有'this'指针的合法转换。使用结构
- 无法将参数从"this"转换为节点<T>*
- 将"this"指针强制转换为另一种类型不违反严格锯齿?
- 无法将"this"指针从"const container"<T>转换为"container<T> &"
- C++ 错误 C2662 无法将"this"指针从"const Type"转换为"Type &"
- STD 向量 push_back' : 2 个重载对"this"指针错误没有合法转换
- 错误 C2663:指针'this'重载没有合法转换
- 错误:错误 C2663:'std::_Tree<_Traits>::insert':2 个重载没有'this'指针的合法转换
- 无法'this'指针从'const CDrawnLabel'转换为'CDrawnLabel &'
- 是否可以将动态强制转换"this"作为返回值?
- 无法将"this"指针从"const Bullet"转换为"Bullet &"
- 将 MSVS 2010 项目转换为 MSVS 2012 RC,但出现错误"The C++ standard doesn't provide a hash for this type"
- 无法将"this"指针从"const Foo"转换为"Foo"错误
- std::使用虚拟呼叫操作员转换抛出"global functions do not have 'this' pointers"
- 无法将指针从'std::stack<_Ty>'转换为'this' 'std::stack<_Ty> &'
- 错误 C2663:'std::_Hash<_Traits>::insert':3 个重载没有'this'指针的合法转换
- 无法转换'this'指针...遗产