constexpr
和之间有什么区别const
?
发布于 2018-01-27 12:51:33
这两个关键字都可以在对象声明和函数中使用。应用于对象的基本区别是:
const
声明一个对象为常量。这意味着一个保证,一旦初始化,该对象的值不会改变,编译器可以利用这个事实进行优化。它还有助于防止程序员编写修改初始化后不打算修改的对象的代码。constexpr
声明一个对象适合在Standard调用常量表达式中使用。但请注意,这constexpr
不是唯一的方法。应用于功能的基本区别是:
const
只能用于非静态成员函数,而不能用于一般函数。它保证了成员函数不会修改任何非静态数据成员。constexpr
可以与成员和非成员函数以及构造函数一起使用。它声明了适用于常量表达式的函数。如果函数符合某些标准(7.1.5 / 3,4),编译器将只接受它,最重要的是(†):
return
允许一个语句。在构造函数的情况下,只允许初始化列表typedefs和静态声明。(= default
和= delete
也被允许使用,但。)如上所述,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
constexpr
并不一定保证在编译时会被评估。它可以用于此类,但也可以在运行时评估的其他地方使用。constexpr
。例:
int main() { const int N = 3; int numbers[N] = {1, 2, 3}; // N is constant expression return 0; }
这是可能的,因为N
在声明时使用常量来保持常量和初始化,即使没有声明,它也满足常量表达式的条件constexpr
。
那么我什么时候需要使用constexpr
?
N
可以作为常量表达式使用而不需要声明constexpr
。所有对象都是如此:
const
[这是由于§5.19/ 2:一个常量表达式不能包括一个子表达式,涉及“左值,右值修改,除非[...]整数或枚举类型的glvalue”感谢理查史密斯纠正我早些时候声称这对所有字面类型都是正确的。]
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 return 0; }
我什么时候可以同时使用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;
return 0;
}
在这里,NP
被声明为一个地址常量表达式,即一个本身就是一个常量表达式的指针。(当通过将地址运算符静态/全局常量表达式生成的地址。这是可能的。)在这里,无论是constexpr
和const
是必需的:constexpr
总是指表达被宣布(在这里NP
),而const
指的是int
(它声明了一个指针-给const)。删除const
会导致表达式不合法(因为(a)非const对象的指针不能是常量表达式,(b)&N
实际上是指向常量的指针)。
B.在成员函数声明中。在C ++ 11中,也constexpr
暗示const
了成员函数。但是,这在C ++ 14中可能会改变。根据目前的草案,由于建议修改§7.1.5/ 8 ,constexpr
将const
仅针对对象,而不针对成员职能。因此,在C ++ 11下声明一个成员函数为
constexpr void f();
将不得不被宣布为
constexpr void f() const;
在C ++ 14下仍然可以用作const
函数。最好将你的constexpr
成员函数标记为const
现在,以免稍后改变很多代码。
发布于 2018-01-27 13:22:04
const
适用于变量,并防止它们在代码中被修改。
constexpr
告诉编译器,这个表达式产生一个编译时间的常量值,所以它可以用在像数组长度,赋值给const
变量等等的地方.Oli给出的链接有很多很好的例子。
基本上他们是两个不同的概念,可以(也应该)一起使用。
发布于 2018-01-27 14:26:29
const
保证一个程序不改变对象的值然而,const
不能保证对象经历哪种类型的初始化。
考虑:
const int mx = numeric_limits<int>::max(); // OK: 运行时初始化
max()
只返回一个文字值。但是,由于初始化程序是函
数调用,mx
运行时初始化。因此,不能将其用作常数表达
式*
int arr[mx]; // error: “constant expression required”
constexpr
是一个新的C++11关键字,它使你不必创建宏和硬编码文字。它还保证,在某些条件下,物体静态初始化它控制表达式的计算时间。通过强制表达式的编译时计算,,,constexpr
让您定义为true常数表达式对于任何依赖编译时常量的代码来说,这对于时间关键的应用程序、系统编程、模板以及一般情况下都是至关重要的。一个常数表达式函数是否声明了一个函数?constexpr
它的主体必须是非虚拟的,并且只包含一个返回语句,除了类型和静态断言。其参数和返回值必须具有文字类型。它可以与非常量表达式参数一起使用,但当这样做时,结果不是常量表达式。
常量表达式函数用于替换宏和硬编码文字在不牺牲性能或类型安全的情况下。
constexpr int max() { return INT_MAX; } // OK
constexpr long long_max() { return 2147483647; } // OK
constexpr bool get_val()
{
bool res = false;
return res;
} // error: body is not just a return statement
constexpr int square(int x)
{ return x * x; } // OK: compile-time evaluation only if x is a constant expression
const int res = square(5); // OK: compile-time evaluation of square(5)
int y = getval();
int n = square(y); // OK: runtime evaluation of square(y)
阿常数表达式对象是声明的对象吗?constexpr
它必须用一个常量表达式或由带有常量表达式参数的常数表达式构造函数构造的rvalue来初始化。
常量表达式对象的行为就像声明了它一样。const
,除非它需要在使用前进行初始化,而且它的初始化程序必须是一个常量表达式。因此,常数表达式对象总是可以作为另一个常量表达式的一部分使用.
struct S
{
constexpr int two(); // constant-expression function
private:
static constexpr int sz; // constant-expression object
};
constexpr int S::sz = 256;
enum DataPacket
{
Small = S::two(), // error: S::two() called before it was defined
Big = 1024
};
constexpr int S::two() { return sz*2; }
constexpr S s;
int arr[s.two()]; // OK: s.two() called after its definition
阿常式构造函数是否声明了构造函数?constexpr
它可以有一个成员初始化列表,但是它的主体必须是空的,除了类型防御和静态断言。其参数必须具有文字类型。
常数表达式构造函数允许编译器在编译时初始化对象,条件是构造函数的参数都是常量表达式。
struct complex
{
// constant-expression constructor
constexpr complex(double r, double i) : re(r), im(i) { } // OK: empty body
// constant-expression functions
constexpr double real() { return re; }
constexpr double imag() { return im; }
private:
double re;
double im;
};
constexpr complex COMP(0.0, 1.0); // creates a literal complex
double x = 1.0;
constexpr complex cx1(x, 0); // error: x is not a constant expression
const complex cx2(x, 1); // OK: runtime initialization
constexpr double xx = COMP.real(); // OK: compile-time initialization
constexpr double imaglval = COMP.imag(); // OK: compile-time initialization
complex cx3(2, 4.6); // OK: runtime initialization
constexpr
对象是Const,并使用编译期间已知的值初始化;constexpr
函数在调用参数时产生编译时的结果,这些参数的值在编译期间是已知的;constexpr
对象和函数可用于比非-constexpr
对象和功能;constexpr
是对象或函数接口的一部分。资料来源:用COMPEER改进C++的安全性、性能和封装...
https://stackoverflow.com/questions/-100007250
复制相似问题