这两个关键字既可以用于对象的声明,也可以用于函数的声明。应用于对象时的基本区别是:
>
const
将对象声明为常量。这意味着一种保证,即一旦初始化,该对象的值就不会改变,编译器可以利用这一事实进行优化。它还有助于防止程序员编写修改对象的代码,而这些对象在初始化后不打算修改。
constexpr
声明一个对象适合在标准的常量表达式中使用。但请注意,constexpr
并不是执行此操作的唯一方法。
如上所述,constexpr
声明了适合在常量表达式中使用的对象和函数。常数表达式不仅仅是常数:
>
它可以用于需要编译时计算的地方,例如,模板参数和数组大小说明符:
template<int N>
class fixed_size_list
{ /*...*/ };
fixed_size_list<X> mylist; // X must be an integer constant expression
int numbers[X]; // X must be an integer constant expression
但请注意:
int main()
{
const int N = 3;
int numbers[N] = {1, 2, 3}; // N is constant expression
}
[这是由于§5.19/2:常数表达式不得包含涉及“lvalue-to-rvalue修改的子表达式,除非[…]整数或枚举类型的glvalue[…]”,这要感谢Richard Smith纠正了我先前的说法,即这对所有文字类型都是正确的。]
>
要使函数适合在常量表达式中使用,它必须显式声明为constexpr
;它仅仅满足常数表达式函数的条件是不够的。示例:
template<int N>
class list
{ };
constexpr int sqr1(int arg)
{ return arg * arg; }
int sqr2(int arg)
{ return arg * arg; }
int main()
{
const int X = 2;
list<sqr1(X)> mylist1; // OK: sqr1 is constexpr
list<sqr2(X)> mylist2; // wrong: sqr2 is not constexpr
}
什么时候可以同时使用const
和constexpr
?
a.在对象声明中。当两个关键字都引用要声明的相同对象时,这永远不是必需的。constexpr
表示const
。
constexpr const int N = 5;
与
constexpr int N = 5;
但是,请注意,可能会出现关键字各自引用声明的不同部分的情况:
static constexpr int N = 3;
int main()
{
constexpr const int *NP = &N;
}
constexpr void f();
constexpr void f() const;
在swift中似乎有两个相等运算符:双相等()和三相等(),这两者有什么区别?
对于定义像下面这样的整型类型的编译时常量(在函数和类作用域),哪种语法是最好的? 也适用于C++98/03编译器,而至少需要C++11。两者之间还有其他区别吗?在现代C++代码中,应该选择其中一个或另一个,为什么? 对于情况,这是GCC6.2生成的程序集: 另一方面,对于,它是: 虽然在中,我得到了相同的(优化的)程序集: 但是,s似乎有不同的行为。我在这里单独提出了一个问题。
我有以下代码: 你能解释一下和以下有什么区别吗? 在这种情况下,我们有什么新发现?
嗨,我对时区没有什么疑问: null 我在维基百科和许多相关网站上搜索过,但没有找到相关的解释
方法接受一个供应商函数接口,该接口本质上不接受任何参数,并返回。 在哪种情况下需要使用?如果您有一个方法为什么不直接执行而不执行? 似乎并不是要将lambda表达式的执行推迟到以后的某个时间或其他时间,那么这有什么意义呢?(我认为如果它返回一个更安全的会更有用,它的从不抛出并且总是返回true...但显然它不是,它只是返回,就像)。 是不是还有什么我遗漏的不同之处?
以下定义有区别吗? 如果不是,在C++11中首选哪种样式?