【发布时间】:2018-09-15 13:09:26
【问题描述】:
我最近遇到了一个对我来说很难找到的错误。我试图将 lambda 传递给采用 std::function 对象的函数。 lambda 正在捕获一个不可复制的对象。
我想通了,显然在所有传球之间一定会发生一些副本。我得出这个结果是因为我总是以 error: use of deleted function 错误结束。
这是产生此错误的代码:
void call_func(std::function<void()> func)
{
func();
}
int main()
{
std::fstream fs{"test.txt", std::fstream::out};
auto lam = [fs = std::move(fs)] { const_cast<std::fstream&>(fs).close(); };
call_func(lam);
return 0;
}
我通过将std::fstream 对象封装在std::shared_ptr 对象中解决了这个问题。这工作正常,但我认为可能有更性感的方式来做到这一点。
我现在有两个问题:
- 为什么会出现此错误?
- 我的想法:我在
for循环中生成了许多fstream对象和lambda,并且对于每个fstream,都有一个lambda 写入它。所以对fstream对象的访问只能由lambdas 完成。我想为一些回调逻辑这样做。有没有像我尝试过的那样使用 lambdas 更漂亮的方法?
【问题讨论】:
-
/OT:不要使用
const_cast,而是将你的lambda标记为mutable。 -
顺便说一句,您的
const_cast是 UB。您不能修改以这种方式投射的对象。正如 Rakete1111 指出的那样,正确的方法是标记对象mutable -
为什么我必须让它可变?
-
@CássioRenan 这里的 UB 是什么?成员变量被捕获为非
const;只有生成的operator()被标记为const。将const从const左值转换为非const对象以修改所述对象是完全没问题的——而且const_cast的全部意义。当然,这里的风格不好,我不认为,但它不是 UB。或者如果是,为什么? -