首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

错误:无法在应使用常量表达式的情况下调用非“const”构造函数。请尝试使用为“const”的构造函数或工厂。容器(

这个错误信息表明在编译时期需要一个常量表达式,但是尝试调用了一个非const构造函数。这种情况通常发生在使用constexpr变量或者在编译时需要确定值的场景中。

基础概念

  • 常量表达式(Constant Expression):在编译时期就可以计算出其值的表达式,常用于数组大小定义、模板参数等。
  • constexpr:C++11引入的关键字,用于指定表达式或对象的值在编译时就可以确定。
  • 构造函数:用于初始化对象的特殊成员函数。

相关优势

  • 使用常量表达式可以提高程序的性能,因为它们在编译时就已经确定,减少了运行时的计算。
  • 有助于编译器进行优化,例如常量折叠。

类型

  • const构造函数:普通的构造函数,可以在运行时调用。
  • const构造函数:特殊的构造函数,用于创建常量对象。

应用场景

  • 当需要在编译时确定对象的值时,例如定义数组大小。
  • 在模板元编程中,需要在编译时进行计算。

问题原因

错误发生的原因是在需要常量表达式的地方调用了非const构造函数。编译器无法在编译时确定非const构造函数的返回值。

解决方法

  1. 使用const构造函数:如果类中有const构造函数,可以直接使用它。
  2. 使用工厂方法:提供一个返回常量的静态成员函数(工厂方法)。
  3. 使用constexpr变量:如果可能,将相关变量定义为constexpr

示例代码

假设有一个类MyClass,它有一个非const构造函数:

代码语言:txt
复制
class MyClass {
public:
    MyClass(int value) : value_(value) {}
    int getValue() const { return value_; }
private:
    int value_;
};

如果尝试在编译时使用它:

代码语言:txt
复制
constexpr MyClass obj(10); // 错误:无法在应使用常量表达式的情况下调用非“const”构造函数

解决方法之一是添加一个const构造函数:

代码语言:txt
复制
class MyClass {
public:
    constexpr MyClass(int value) : value_(value) {}
    int getValue() const { return value_; }
private:
    int value_;
};

或者使用工厂方法:

代码语言:txt
复制
class MyClass {
public:
    static constexpr MyClass create(int value) {
        return MyClass(value);
    }
    int getValue() const { return value_; }
private:
    int value_;
};

constexpr MyClass obj = MyClass::create(10); // 正确

参考链接

通过上述方法,可以解决在编译时需要常量表达式但调用非const构造函数的问题。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

读完某C++神作,我只记下了100句话

const把一个对象转换成一个常量const int bufSize = 512】。 全局变量加const作用域只本文件。再加extern可在整个程序访问。const变量默认为extern。...静态变量只初次调用时初始化,static size_t ctr=0只执行一次。 内联函数避免函数调用开销:编译时展开为函数体中表达式,免去函数调用寄存器保存恢复、复制实参跳转等。...假设有成员函数bool same_isbn(..) const 最后const改变了隐含this形参类型,这种成员函数常量成员函数无法修改对象本身。...const对象,指针引用只能调用常量成员函数。 没有前缀成员都被假定为this调用。 默认构造函数按变量初始化规则初始化类中所有成员【内置类型作为局部变量时不初始化】。...构造函数是对象动态类型确定之前运行,不需要定义为virtual。 引用、对象、指针静态类型决定了能够完成行为,动态类型有多功能也无法使用。派生类避免与基类成员名字冲突。

1.4K20

Google C++ 编程风格指南(五):其他 C++ 特性

其一,位于 .cc 文件里静态函数匿名空间函数,毕竟都只能在局部文件里调用函数了。 其二,可以构造函数里用缺省参数,毕竟不可能取得它们地址。 其三,可以用来模拟变长数组。...定义: 对于变量自增 (++i i++) 自减 (--i i--) 后表达式值又没有没用到情况下, 需要确定到底是使用前置还是后置自增 (自减)....因此, 我们强烈建议在任何可能情况下使用 const: 如果函数不会修改传你入引用指针类型参数, 该参数应声明为 const. 尽可能将函数声明为 const. 访问函数应该总是 const....其他不会修改任何数据成员, 未调用 const 函数, 不会返回数据成员 const 指针引用函数也应该声明成 const....考虑一下你们团队成员平均水平是否能够读懂并且能够维护你写模板代码.或者一个c++ 程序员和一些只是在出错时候偶尔看一下代码的人能够读懂这些错误信息或者能够跟踪函数调用流程.

1.1K30
  • 『Flutter开发实战』一小时掌握Dart语言

    使用常量构造函数构造函数名之前加 const 关键字,来创建编译时常量时: var p = const ImmutablePoint(2, 2); 两个使用相同构造函数相同参数值构造编译时常量是同一个对象... 常量上下文 场景中,你可以省略掉构造函数字面量前 const 关键字。...调用父类默认构造函数 默认情况下,子类构造函数调用父类匿名无参数构造方法,并且该调用会在子类构造函数函数体代码执行前,如果子类构造函数还有一个 初始化列表,那么该初始化列表会在调用父类构造函数之前被执行...mute) print(msg); } } 备忘: 工厂构造函数无法访问 this。...Future 对象代表一个“承诺”,await 表达式会阻塞直到需要对象返回。 如果在使用 await 时导致编译错误确保 await 一个异步函数使用

    5.1K10

    C++关键知识点梳理

    引用只能绑定在对象上,而不能与字面量或者某个表达式计算结果绑定在一起;const 指针 & 引用函数指针:指向另一类型对象,是对象不是别名,所以不需要定义时初始化,但是未经初始化指针容易引发运行时错误...:指针本身是常量,不能指向其他对象,例如 int *const p1=&i,const int ci =42;底层指针:指针所指向对象是常量const int *p2=&ci;常量类中使用:对于不修改类成员变量成员函数...,例如,get操作成员函数最好定义为常量成员函数常量对象、常量对象引用指针都只能调用常量成员函数。...默认构造函数没有参数,没有定义任何构造函数情况下,编译器会帮我们自动定义默认构造函数,否则我们定义了其他构造函数后,一定要显示定义默认构造函数;析构函数拷贝构造函数赋值构造函数访问控制和封装:this...类设计工具拷贝、赋值、销毁拷贝构造函数:将一个对象作为引用实参、将一个引用对象直接作为函数返回值、用花括号列表初始化一个数组或者一个类成员时均使用了拷贝构造函数

    97030

    Dart语法详解系列篇(二)-- 类与函数八、Dart类与函数

    构造函数 常量上下文中,您可以省略const构造函数文字之前内容。...'line': [ImmutablePoint(1, 10), ImmutablePoint(-2, 11)], }; 如果一个常量构造函数常量上下文之外,并且没有常量情况下调用,则会创建一个非常量对象...{y}'); // } } 6.构造函数调用流程 默认情况下,子类中构造函数调用超类无参构造函数。超类构造函数构造函数开头被调用。如果 还使用初始化列表,则在调用超类之前执行。...y; const Test(this.x, this.y); } 9.工厂构造函数 factory是实现不总是创建其类新实例构造函数使用关键字。...如果要在不继承B实现情况下创建支持B类APIA类,则A类实现B接口。 一个类通过implements子句中声明它们然后提供接口所需API来实现一个多个接口。

    2.9K30

    Dart语言指南(二) 顶

    使用常量构造函数创建编译时常数,请使用const 代替 new: var p = const ImmutablePoint(2, 2); 构造两个相同编译时常量导致一个单一规范实例: var a...如果要使用父类中定义命名构造函数创建子类,则必须在子类中实现该构造函数. 调用父类默认构造函数 默认情况下,子类中构造函数调用超类未命名无参数构造函数。...超类构造函数构造函数起始处被调用。 如果一个 初始化器列表 也被使用,它将在超类被调用之前执行。...使用延期加载时,记住以下几点: 延迟库常量不是导入文件中常量。 记住,这些常量加载延迟库之前不存在. 您不能在导入文件中使用延迟库中类型。...此Future对象表示返回对象承诺. await 表达式 值是返回对象. await 表达式使执行暂停,直到该对象可用. 如果await 不起作用, 确保它处于异步函数中.

    3.1K20

    【笔记】《C++Primer》—— 第一部分:C++基础

    它还可以将编译器无法自动执行类型进行转换,例如将void*转为其他指针类型 const_cast比较危险,可以强制去除对象const,要注意const_cast只能改变const性质,无法改变表达式类型...我们无法在这个函数中修改这个对象内容 一般来说当一个函数概念上属于某个类但并不在类内,则将其与类声明放在同一个文件中 对象是构造初始化完成后(执行构造函数体前瞬间)获得const引用等属性...因此一方面是最好保持参数顺序与声明顺序相同以方便查找,另一方面尽量避免用某些成员来初始化其他成员以防止初始化顺序导致问题 C11增加了“委托构造函数”,即可以构造函数初始值列中调用委托构造函数了...想使用默认构造函数时,方法是初始化对象时不使用后面的调用运算符(即小括号对),如直接写Test a; 当构造函数*只接受一个*实参时,称转换构造函数,即定义了这种类型隐式转换机制,在这种情况下我们对实参输入编译器可以自动地进行...构造函数,成员若有类内初始值则必由字面值常量其自己constexpr构造且类必须使用默认析构函数类,称为字面值常量类 static关键字只出现在类声明里,不能在外部重复这个关键字,最好将其定义与其他内联函数放在一起以保证唯一次定义

    1.5K40

    《Effective Modren C++》 进阶学习(上)

    理解auto类型推导 大部分情况下auto推导与模板类型推导一致,仅当变量使用花括号初始化时,auto能够推导成std::initializer_list,而模板类型推导则无法推导。...因此使用时可参考如下场景使用 复杂类型名称较长: 当变量类型名称非常冗长复杂时,使用auto可以简化代码并提高可读性。例如,当类型名称包含模板嵌套类型时,使用auto可以减少输入错误。...常量表达式是在编译时求值表达式,可用于变量函数构造函数。...constexpr常量可以在编译时被用作常量表达式,例如作为数组大小、模板参数其他需要常量表达式上下文中使用。这样可以提高代码灵活性和可读性。 编译时错误检查。...使用constexpr可以在编译时对常量表达式进行类型检查和错误检查。如果在常量表达式使用了不允许操作无效值,编译器会在编译时发出错误警告,帮助我们及早发现并修复问题。 16.

    19620

    【笔记】《深入理解C++11》(上)

    初始化列表效果总是慢于就地初始化, 但也快过构造函数中进行赋值 注意: 非常量静态变量依然要在头文件外定义从而保证程序中只存在一个 sizeof()可以对类成员表达式使用了 类模板也可以声明友元了...3 通用为本, 专用为末 继承构造 为了减少派生类层层透传函数以复用基类代码情况, 可以类内用using Base::Func;来获取基类被隐藏同名成员函数(包括构造函数, 此时被称为继承构造函数...其他构造函数通过带有默认值委派构造调用这个目标构造函数 千万小心环形委派, 会导致编译错误 委派构造函数使得构造函数模板编程也成为一种可能, 通过让模板构造函数成为委派构造函数, 我们可以很容易地接受多种不同类型参数进行相同底层初始化...failure, 不会引发error, 直到完成所有尝试 基础来说, SFINEA使得模板实例化过程各个编译器上都能表现出一样效果, 且避免不相关模板可见时实例化出错误程序....auto和cv限制符(cv-qualifier, 指const和volatile)一起使用时, auto无法带走变量cv限制, 因此需要我们额外写清楚对应限制 auto可以用来一个表达式中声明多个变量

    1.9K20

    c++从入门到进阶--引用与常量

    constexpr函数必须满足下述限制: 函数返回值不能是void类型 函数体不能声明变量定义新类型 函数体只能包含声明、null语句或者一条return语句 形参实参结合后,return语句中表达式常量表达式...返回引用类型函数 连同算术、关系、位运算、后缀自增自减运算符、字面值常量、要求转换表达式。...string对象这个string对象函数str()语句结束就会被销毁,一般使用先声明一个string对象s,将str()赋值给sconst string s=ss.str();或者const string...③引用传递 引用传递是以引用为参数,则既可以使得对形参任何操作都能改变相应数据,又使函数调用方便。引用传递是形参调用前加入引用运算符“&”。...函数执行完函数最后一条语句遇到return语句时返回。

    77920

    左值和右值、左值引用与右值引用、移动语句(2)「建议收藏」

    它可以是函数名称取消引用函数指针结果。 C语言还区分它对函数指针和对象指针处理。 另一方面,C ++中,返回引用函数调用是左值。否则,函数调用是rvalue表达式。...以下表达式是xvalues: 调用返回类型为右值引用类型函数结果 强制转换为右值参考 通过xvalue表达式访问引用类型静态数据成员 指向成员访问表达式指针,其中第一个操作数是xvalue...另外,编译器永远不会自动生成move版本构造函数和赋值函数,它们需要你手动显式地添加。 当添加了move版本构造函数和赋值函数重载形式后,某一个函数调用应当使用哪一个重载版本呢?...3、非常量值优先绑定到非常量引用上。 当给构造函数赋值函数传入一个非常量右值时,依据上面给出判决规则,可以得出会调用move版本构造函数赋值函数。...这是因为move构造函数中,s虽然是一个非常量右值引用,但其本身却是一个左值(是持久对象,可以对其取地址),因此调用*this = s时,会使用拷贝赋值函数而不是move赋值函数,而这已与move构造函数语义不相符

    2.6K20

    C++查缺补漏

    () { return 20; } constexpr int foo = get_size(); //正确:foo是一个常量表达式 重载函数 通过形参个数不同或者类型不同进行区分 无法通过返回值区分...为了确保数据完整性,及数据封装与隐藏原则,建议尽量不使用使用友元 友元函数 友元函数类声明中由关键字friend修饰说明非成员函数函数体中能够通过对象名访问 private 和protected...,则通过派生类对象使用是派生类中同名成员 如要通过派生类对象访问基类中被隐藏同名成员,使用基类名和作用域操作符(::)来限定 如果从不同基类继承了同名成员,但是派生类中没有定义同名成员,“派生类对象名引用名...双目运算符重载规则 如果要重载 B 为类成员函数使之能够实现表达式 oprd1 B oprd2,其中 oprd1 为A 类对象,则 B 被重载为 A 类成员函数,形参类型应该是 oprd2 所属类型...经重载后,表达式 U oprd 相当于 oprd.operator U() 后置单目运算符 ++和--重载规则 如果要重载 ++--为类成员函数使之能够实现表达式 oprd++ oprd-- ,

    2.6K10

    C++ 特性使用建议

    (4)异常是处理构造函数失败唯一途径,虽然可以用工厂模式产生对象 Init() 方法代替异常,但是前者要求堆栈分配内存,后者会导致刚创建实例处于 ”无效“ 状态。...因此, 我们强烈建议在任何可能情况下使用 const: (1)如果函数不会修改传你入引用指针类型参数,该参数应声明为 const。 (2)尽可能将函数声明为 const。...访问函数应该总是 const。其他不会修改任何数据成员,未调用 const 函数,不会返回数据成员 const 指针引用函数也应该声明成 const。...(3)如果数据成员在对象构造之后不再发生变化,可将其定义为 const。 13.constexpr 用法 C++11 里,用 constexpr 来定义真正常量实现常量初始化。...考虑一下你们团队成员平均水平是否能够读懂并且能够维护你写模板代码。或者一个C++ 程序员和一些只是在出错时候偶尔看一下代码的人能够读懂这些错误信息或者能够跟踪函数调用流程。

    1.7K20

    AngularDart4.0 指南- 依赖注入 顶

    元数据注解必须是对编译时常量变量引用,对Injectable()等常量构造函数调用。 如果忘记括号,分析器将会抱怨:“注解创建必须有参数”。...如果您尝试运行应用程序,它将无法正常工作,控制台会说“表达式必须是编译时常量”。 Providers 服务提供者提供依赖性值具体运行时版本。...您可以配置一个可以传递Logger注入器代替供应商,你可以提供一个替代类。 你可以给它一个调用一个记录器工厂函数提供者,正确情况下,任何这些方法都可能是一个不错选择。...请注意,您在一个常量,heroServiceProvider中捕获了工厂提供者。 这额外步骤使工厂提供者可重用。 你可以需要时候用这个常量注册HeroService。...他们通过调用injector.get()来检索。 如果get()方法无法解析请求服务,则会引发错误。 您可以使用第二个参数调用get(),如果未找到该服务,则返回该值。

    5.7K20

    重温 CC++ 笔记

    lambda 表达式不是函数是变量,但可以像函数一样被调用 字符串拷贝、修改代价比较高,应当尽量用 const string& 方式来引用字符串 原始指针可以拷贝,符合值语义,可以放进容器...= delete 表示明确禁用某个函数构造、析构也可以用),让外界无法调用 C++ 有隐式构造和隐式转型规则。 隐式类型转换:类型 A 被自动转成表达式需要类型 B。...const 可以修改引用和指针,const& 是函数参数最佳选择 修饰成员函数的话,这个函数只能访问常量变量;const 函数,实际上是传入一个 const this const 常量预处理阶段不存在...编译器看到 const 常量会做一些优化,比如把这个变量直接换成对应值 只读指针对象,调用方法,只能调用 const const_cast,去常量化,变成普通变量 volatile 表示变量会随时会被修改... #include #include 容器里存储是元素拷贝、副本,而不是引用,尽量为元素实现转移构造和转移赋值函数加入容器时候使用 std

    1.3K30

    第 13 章 拷贝控制

    使用=定义变量 将一个对象作为实参传递给一个引用类型形参 从一个返回类型为引用类型函数返回一个对象 用花括号列表初始化一个数组中元素一个聚合类中成员 标准库容器插入元素(insert...如果类某个成员析构函数是删除不可访问,或是类有一个没有类内初始化器引用成员,或是类有一个没有类内初始化器且无法默认构造 const成员,则该类默认构造函数被定义为删除。...在这些情况下,移动而非拷贝对象会大幅度提升性能。另外,就是像 IO类 unique_ptr这样类,本身不能被拷贝,但可以移动。 旧标准中,容器保存对象只能使用拷贝,效率往往较低。...左值表达式通常表示是一个对象身份,不能将其绑定到要求转换表达式、字面常量和返回右值表达式。 返回引用类型函数,连同算术、关系、位以及后置递增/递减运算符,都返回右值。...i * 42; // 正确 左值有持久状态,而右值要么是字面常量,要么是表达式求值过程中创建临时对象。

    1K50

    C++11新特性学习笔记

    声明类型枚举非常简单,只需要在enum后加上使用classstruct。...返回语句表达式中不能使用常量表达式函数、全局数据,且必须是一个常量表达式 常量表达式构造函数有以下限制: 函数体必须为空 初始化列表只能由常量表达式来赋值 3.7 用户定义字面量(vs2013...那么这个加法赋值表达式中,&a是允许操作,但&(b + c)这样操作则不会通过编译。因此a是一个左值,(b + c)是一个右值。 相对于左值,右值表示字面常量表达式函数引用返回值等。...可以对动态资源进行管理,保证任何情况下,已构造对象最终会销毁,即它析构函数最终会被调用。...函数体内可以使用lambda所在类中成员变量。 n a。将a按值进行传递。按值进行传递时,函数体内不能修改传递进来a拷贝,因为默认情况下函数const

    2.2K20

    C++11新特性学习笔记

    声明类型枚举非常简单,只需要在enum后加上使用classstruct。...返回语句表达式中不能使用常量表达式函数、全局数据,且必须是一个常量表达式 常量表达式构造函数有以下限制: 函数体必须为空 初始化列表只能由常量表达式来赋值 3.7 用户定义字面量(vs2013...那么这个加法赋值表达式中,&a是允许操作,但&(b + c)这样操作则不会通过编译。因此a是一个左值,(b + c)是一个右值。 相对于左值,右值表示字面常量表达式函数引用返回值等。...可以对动态资源进行管理,保证任何情况下,已构造对象最终会销毁,即它析构函数最终会被调用。...函数体内可以使用lambda所在类中成员变量。 n a。将a按值进行传递。按值进行传递时,函数体内不能修改传递进来a拷贝,因为默认情况下函数const

    2.1K20

    Effective C++: 改善程序与设计55个具体做法

    条款02:尽量以const,enum,inline替换#define 记住 ■ 对于单纯常量,最好以const对象enums替换#defines。...■ 对于形似函数宏(macros),最好改用inline函数替换#defines。 条款03:尽可能使用const 记住 ■ 将某些东西声明为 const可帮助编译器侦测出错误用法。...条款09:绝不在构造和析构过程中调用virtual函数 记住 ■ 构造和析构期间不要调用virtual函数,因为这类调用从不下降至derived class(比起当前执行构造函数和析构函数那层)。...条款16:成对使用new和delete时要采取相同形式 记住 ■ 如果你new表达式使用[],必须在相应delete表达式中也使用[]。...■ 调用swap时针对std::swap使用using声明式,然后调用swap并且不带任何“命名空间资格修饰”。

    71020

    《C++Primer》第十三章 拷贝控制

    拷贝构造函数几种情况下都会被隐式地使用,因此拷贝构造函数通常不应该是explicit。 1.1 合成拷贝构造函数 当我们没有为一个类定义拷贝构造函数时,编译器会为我们定义一个。...拷贝初始化除了我们用=定义变量时会发生,在下列情况下也会发生: 将一个对象作为实参传递给一个引用类型形参 从一个返回类型为引用类型函数返回一个对象 用花括号列表初始化一个数组中元素一个聚合类中成员...参数和返回值 函数调用过程中,具有引用类型参数要进行拷贝初始化 当一个函数具有引用返回类型时,返回值会被用来初始化调用结果 拷贝构造函数被用来初始化引用类类型参数,这一特性解释了为什么拷贝构造函数自己参数必须是引用类型...,或是类有一个const引用成员,则类合成拷贝构造函数被定义为删除 如果类某个成员析构函数是删除不可访问,或是类有一个引用成员,他没有类内初始化器,或是类有一个const成员,他没有类内初始化器且未显式定义默认构造函数...1.1 左值持久而右值短暂 左值有持久状态,但是右值要么是字面常量,要么是表达式求值过程中创建临时对象。

    1.6K40

    扫码

    添加站长 进交流群

    领取专属 10元无门槛券

    手把手带您无忧上云

    扫码加入开发者社群

    相关资讯

    热门标签

    活动推荐

      运营活动

      活动名称
      广告关闭
      领券