当前位置: 首页 > 知识库问答 >
问题:

c++ - 为什么变量被编译器声明为const?

章彬郁
2024-02-20

变量被编译器声明为const,导致无法编译

#include <vector>#include <functional>class Widget {public:    void addFilter() const;private:    int divisor;     using FilterContainer =         std::vector<std::function<bool(int)>>;     FilterContainer filters;                   };void Widget::addFilter() const{    filters.emplace_back(        [=](int value) { return value % divisor == 0; }    );}int main(){    ;}

3cfb0110448c37089ccff8e55b40621.png

共有2个答案

程鸿煊
2024-02-20
void Widget::addFilter() const                      // ^^^^^{    filters.emplace_back(        [=](int value) { return value % divisor == 0; }    );}

这个自己声明的 const 。

这个 const 导致 this 变成 const,从而所有的成员都是 const ,比如里面的 filters (它其实是 this->filters)

田信然
2024-02-20

你的代码中,Widget 类有一个 addFilter 成员函数,它被声明为 const。这意味着这个函数不会修改 Widget 类的任何成员变量。然而,在你的 addFilter 实现中,你试图通过 filters.emplace_back() 添加一个新元素到 filters 容器中。这会调用一个 lambda 函数,该函数捕获 divisor 变量。这会试图修改 divisor,这与你 const 函数的声明相冲突。

如果你希望 addFilter 不修改任何成员变量,你可以去掉 divisor 的 lambda 捕获,或者将 addFilter 改为非 const 成员函数。

如果你希望 addFilter 可以修改 divisor,那么你需要去掉 addFilterconst 声明。

这是一个简单的示例,展示了如何使 addFilter 不修改任何成员变量:

#include <vector>#include <functional>class Widget {public:    void addFilter() const;private:    int divisor = 10; // 初始化 divisor 的值,以避免未初始化的值可能引发的问题    using FilterContainer =         std::vector<std::function<bool(int)>>;     FilterContainer filters;                   };void Widget::addFilter() const{    filters.emplace_back(        [=](int value) { return value % divisor == 0; } // 这里不再捕获 divisor    );}
 类似资料:
  • 问题内容: 我是golang的新手,我编写了一个测试io包的程序: 编译错误为“已声明并且未使用err”。但是我想我已经使用err来声明。为什么编译器会输出此错误? 问题答案: for 的内部正在遮盖for的外部,并且未被使用(for的内部)。发生这种情况的原因是,您正在使用简短的变量声明(与运算符一起使用),该声明声明了一个新变量,该新变量遮盖了for外部声明的变量。

  • 为什么 C 编译器可以将函数声明为 constexpr,而 constexpr 不能是 constexpr? 例如:http://melpon.org/wandbox/permlink/AGwniRNRbfmXfj8r 输出: 为什么此行出错:

  • 问题内容: 为什么即使该类中没有抽象方法,也将类声明为抽象? 问题答案: 这是因为它遵循模板方法设计模式。这些方法具有返回HTTP 405 未实现方法 错误的所有默认行为。如果所有这些方法都是抽象的,那么即使您的业务需求根本不需要它们,也将不得不覆盖所有这些方法。这只会导致样板代码和不确定/不直观的行为。

  • 我正在讨论以下问题:使用Java 8的可选和stream::FlatMap并希望向自定义的添加一个方法,然后检查它是否工作。 更准确地说,我希望向我的添加一个。如果不存在值,则返回一个空流,如果存在,则返回一个包含单个元素的流。 但是,我得出的结论是,声明为final。 为什么会这样呢?有一些类没有声明为final,我个人认为这里没有理由声明final。 作为第二个问题,为什么不是所有的方法都是f

  • 问题内容: 以下方法不起作用,因为内部块声明的变量与外部块中的变量同名。显然,变量属于声明它们的方法或类,而不属于声明它们的块,因此,我无法编写一个简短的临时临时块进行调试,而恰好将外部作用域中的变量压入阴影只是片刻: 我使用过的几乎每种块范围语言都支持此功能,包括我在学校为解释器和编译器编写的琐碎小语言。Perl可以做到这一点,Scheme甚至C都可以做到。甚至PL / SQL也支持这一点! J

  • 我正在标准中寻找对这一事实的正式解释。我找到了3.9.1/9所说的,并试图用该部分给出解释。 第3.9.1/9节,N3797: void类型有一组空值。void类型是不完整的类型,无法完成。它用作不返回值的函数的返回类型。任何表达式都可以显式转换为cv void类型(5.4)。void类型的表达式只能用作表达式语句(6.2)、逗号表达式的操作数(5.18)以及?的第二个或第三个操作数:(5.16)