必须在编译时知道数组维度,这意味着维度必须是常量表达式
另外一点是这样的
unsigned count = 42; // not a constant expression
constexpr unsigned size = 42; // a constant expression
Run Code Online (Sandbox Code Playgroud)
我会,然后期望以下声明失败
a[count]; // Is an error according to Primer
Run Code Online (Sandbox Code Playgroud)
但事实并非如此.编译并运行良好.
还有一点奇怪的是,++count;在数组声明之后也没有引起任何问题.
用-std=c++11flag打开的程序g++4.71
这是为什么?
constexpr在我看来,C++ 11的功能,以及模板参数包应该足够强大,可以执行一些相当复杂的计算.我有一个实际应用的一个可能的例子是在编译时计算第n个素数.
我在想办法实现这个计算.如果提出了多个解决方案,那么比较它们可能会很有趣.
为了让你了解我的性能预期:我希望有一些代码可以在合理的桌面硬件上在不到一秒的编译时间内找到第512个素数(即3671).
在以下示例中:
//Case 1
constexpr int doSomethingMore(int x)
{
return x + 1;
}
//Case 2
constexpr int doSomething(int x)
{
return ++x;
}
int main()
{}
Run Code Online (Sandbox Code Playgroud)
输出:
prog.cpp:在函数'constexpr int doSomething(int)'中:
prog.cpp:12:1:错误:表达式'++ x'不是常量表达式
为什么案例1被允许但案例2不被允许?
我很难理解这段代码(C++ 14草案标准[conv.lval]中的一个例子)是如何调用未定义的行为的g(false).为什么constexpr让程序有效?
另外,"不访问y.n" 是什么意思?在两个调用中g()我们都返回n数据成员,为什么最后一行说它不访问它?
struct S { int n; };
auto f() {
S x { 1 };
constexpr S y { 2 };
return [&](bool b) { return (b ? y : x).n; };
}
auto g = f();
int m = g(false); // undefined behavior due to access of x.n outside its
// lifetime
int n = g(true); // OK, does not access y.n
Run Code Online (Sandbox Code Playgroud) 我理解这constexpr将允许您在编译时将对象用作常量,但是什么时候这将是有益的?我试图更好地理解关键字,但是在构造函数上使用它时,我找不到一个很好的例子来解释它为什么需要它.
下面的两个例子都有用,那么为什么constexpr放在构造函数上呢?
使用constexpr构造函数:
#include <iostream>
using namespace std;
class Rect
{
public:
constexpr Rect(int width, int height)
: mWidth(width), mHeight(height) {}
constexpr int getArea() const { return mWidth * mHeight; }
private:
int mWidth, mHeight;
};
int main(int argc, char* argv[])
{
constexpr Rect r(8, 2);
cout << r.getArea() << endl; //16
int myArray[r.getArea()]; // OK
return 0;
}
Run Code Online (Sandbox Code Playgroud)
没有constexpr构造函数:
#include <iostream>
using namespace std;
class Rect
{
public:
Rect(int width, int height)
: mWidth(width), mHeight(height) {}
constexpr …Run Code Online (Sandbox Code Playgroud) 根据std::weak_ptr文档,可以构建一个constexpr weak_ptr:
#include <memory>
constexpr weak_ptr<int> foo{};
Run Code Online (Sandbox Code Playgroud)
但是,使用clang尝试这个会产生一个编译错误,抱怨constexpr变量不能有非文字类型' const std::weak_ptr<int>',这是因为weak_ptr<int>有一个用户提供的析构函数.(确实如此,查看libc ++标头)
我的问题是,这是一个libc ++错误,还是constexpr weak_ptr没有意义,并且constexpr默认构造函数是错误的?我可以期待这种情况在未来发挥作用吗?
我写了这样的代码
#include <iostream>
using namespace std;
constexpr int getsum(int to){
int s = 0;
for(int i = 0; i < to; i++){
s += i;
}
return s;
}
int main() {
constexpr int s = getsum(10);
cout << s << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我知道它的工作原理是因为扩展了constexpr.然而,在这个问题为什么不是一个for-loop-a-compile-time-expression,作者给出了他的代码如下:
#include <iostream>
#include <tuple>
#include <utility>
constexpr auto multiple_return_values()
{
return std::make_tuple(3, 3.14, "pi");
}
template <typename T>
constexpr void foo(T t)
{
for (auto i = 0u; i < …Run Code Online (Sandbox Code Playgroud) 在Wiki中找到以下声明:
C++ 11引入了constexpr声明函数的概念; 一个可以在编译时执行的函数.它们的返回值可能由需要常量表达式的操作使用,例如整数模板参数.但是,C++ 11 constexpr函数只能包含一个返回的表达式(以及static_asserts和少量其他声明).
C++ 14放宽了这些限制.Constexpr声明的函数现在可以包含以下内容:条件
- ...
- 分支声明
if和switch
那么,实际上是否可以在c ++ 14/c ++ 17中的constexpr函数中进行切换?而且,如果可能的话,那是什么语法?例如,我想要这样的东西:
enum class Terrain : std::uintmax_t {
ROAD,
SOIL,
GRASS,
MUD,
SNOW,
};
constexpr float
getStepPrice(Terrain const& terrain)
{
switch constexpr (terrain)
{
case Terrain::ROAD: return 1.0f;
...
}
}
Run Code Online (Sandbox Code Playgroud) #include <iostream>
using namespace std;
constexpr int r =100;
int main()
{
constexpr int &k = r ;
cout << k << endl;
}
Run Code Online (Sandbox Code Playgroud)
编译此代码会在编译时将"error:binding'const int'引用为类型'int&'丢弃限定符".
我有以下示例:
#include <array>
struct A {
const char* str;
const char* str2;
};
template<size_t N>
struct As {
std::array<A,N> elems_;
};
template<class... Args>
As(Args...)->As<sizeof...(Args)>; //<-- NOTE: deduction guide !
constexpr static As as{A{"a","b"}, A{"1","2"}};//<-- 'retyping' A here
int main() {
return as.elems_.size();
}
Run Code Online (Sandbox Code Playgroud)
尽管此代码有效,但我想避免在A汇总列表中对的“重新键入” ,但是如果不加说明,则推导指南将失败:("cannot deduce template arguments for 'As'"我想这很有意义)。解决此问题的一种方法可能是通过手写我需要的任意数量的扣除指南,此后我可以A在每个扣除指南中编写类型(即:针对我需要的每种尺寸的容器进行一次扣除)。
c++ language-lawyer aggregate-initialization constexpr c++17
c++ ×10
constexpr ×10
c++11 ×5
c++14 ×3
c++17 ×2
arrays ×1
compile-time ×1
destructor ×1
weak-ptr ×1