c++ - 如何判断表达式是在编译时还是运行时评估的?
问题描述
我有一个相当大的 Map 对象,我想要一个单独的列表来排序键。这将在我项目的许多其他源文件中使用。
问题是我如何知道声明/定义何时是编译时作业。如果是这种情况,我应该在哪里寻找?我的意思是怎么讲?
在以下示例中,源文件中的列表是编译时作业还是发生在运行时?
另外,有没有办法在编译时进行排序操作?
// global.h
extern QMap<int, QString> G_MAP;
extern QList<int> G_MAP_SKEYS_SORTED;
// global.cpp
QMap<int, QString> G_MAP = { /* some hand filled (static) data */ };
QList<int> G_MAP_SKEYS_SORTED = G_MAP.keys();
// main.cpp
int mian() {
// Somewhere I do the sort
std::sort(G_ListRegistersSorted.begin(), G_ListRegistersSorted.end());
}
解决方案
如果将结果分配给constexpr
变量、在static_assert
ornoexcept
语句中使用或用作模板参数,则在编译时计算表达式。这称为 constexpr 上下文。
例如:
// Function which can calculate the fibbonacci sequence at compiletime
constexpr int fib(int n) {
if(n == 0 || n == 1) return n;
return fib(n - 1) + fib(n - 2);
}
int main() {
// This one is calculated at compiletime
constexpr int fib10_at_compiletime = fib(10);
// This one is calculated at runtime
// (unless the compiler was really aggressive when doing optimizations)
int fib10_at_runtime = fib(10);
}
In order to call a function or something at compiletime, it needs to be marked constexpr
.
What can you do at compiletime?
C++11:
- Declare variables (but not modify them)
- Call other constexpr functions
- Call constexpr constructors (and default ones)
- Use carrays and
std::array
- Use static_asserts and stuff
typedef
andusing
declarations
C++14 additions:
- You can also use lambdas now
- You can modify variables inside a constexpr function
- you can have constexpr member functions that change member variables
- you can pass references (the non-const kind) to constexpr functions
C++20 additions: (C++20 is coming out in 2020)
- You can allocate memory now
- You can call virtual functions now
- You can have
try-catch
blocks
Is std::sort
constexpr?
In order to use a function in a constexpr context, it must be marked constexpr (which comes with a set of restrictions on what you can do in the function; these are discussed below). In C++11, std::sort
isn’t constexpr because it breaks those restrictions (and it won’t be constexpr until C++20).
However, if you’re allowed to use C++14, you can write your own sorting function that works at compile time.
Full overview: https://en.cppreference.com/w/cpp/language/constexpr
推荐阅读
- c# - 类存储在 MongoDB (C#) 中,包含内部数组。需要更新嵌套数组中的单个元素,有什么更好的方法呢?
- python - Python将“pandas.core.series.Series”列表从地图调用折叠成数据框
- c# - 文件无法重写,因为其他进程使用该文件
- javascript - 反应路由器历史推送总是路由到 404 页面
- go - Golang - 结构上缺少表达式错误
- reactjs - 使用 Context API 动态设置抽屉位置时,React 导航抽屉无法始终打开
- html - Css 覆盖父级的子级颜色
- sql - 从十进制中删除一些尾随零
- c# - .Net Core 3.1 App 部署后未在 IIS 中自动启动
- javascript - 如何在 js 中显示字形图标?