【问题标题】:Can I capture an object as a const when using init caputre?使用初始化捕获时,我可以将对象捕获为 const 吗?
【发布时间】:2020-03-03 14:33:21
【问题描述】:

当使用 C++14 的初始化捕获时,会应用 'auto' 类型推导规则(这会丢弃引用、const 和 volatile)

请注意,我不是在说 const 引用。如果我想要一个 const 引用,我可以写:

auto lambda = [&widget = std::as_const(widget)] () {};
// C++17

或者我可以在 lhs 中添加 & 将 rhs 转换为 const 引用。

我要问的是:我可以写这样的东西吗?:

auto lambda = [const widget = widget] () {};

【问题讨论】:

  • 为什么需要const widget? lambda 的operator () 已经是const(除非您将其标记为mutable),因此您无法更改函数内的值对象捕获。
  • 还有,如果您有const 参考或const 副本,这有什么关系?我的意思是如果你想要它const,就不需要复制
  • @NathanOliver 我不明白为什么我现在需要它。只是想知道是否有办法做到这一点,以防万一我使用“可变”并希望某些变量保持不可修改。
  • 你以后也不需要它,当你可以使用 const 引用时;)
  • @idclev463035818 是的,你是对的。我不认为我会需要它。只是想知道我是否可以这样做。

标签: c++ lambda type-deduction


【解决方案1】:

无法按值捕获对象并将其设为constinit-capture 的语法是

init-capture:
    identifier initializer
    & identifier initializer

identifier 在哪里

identifier:
    identifier-nondigit
    identifier identifier-nondigit
    identifier digit

这意味着您只能指定一个名称,而不能指定任何 cv 限定符。对于非可变 lambda,这不是问题,因为该函数将是 const,并且您无法修改按值对象的捕获。

对于可变 lambda,您可以像使用 [&widget = std::as_const(widget)] 一样捕获对 const 的引用。如果您不能或不想有参考,那么您需要编写一个类似的 const 包装器

template <typename T>
class const_wrapper
{
    const T obj;
public:
    const_wrapper(T obj) : obj(obj) {}
    operator const T&() const { return obj; }
};

上面的对象是可复制的,但不可赋值(因为有 const 成员),并且只允许 const 访问底层类型。

【讨论】:

    猜你喜欢
    • 2016-10-08
    • 1970-01-01
    • 1970-01-01
    • 2014-11-23
    • 2020-09-17
    • 2016-12-10
    • 2013-04-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多