我有一个相当大的 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
或 noexcept
语句中使用,或使用作为模板参数。这称为 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);
}
为了在编译时调用一个函数什么的,需要标记为constexpr
。
在编译时你能做什么?
C++11:
- 声明变量(但不修改它们)
- 调用其他constexpr函数
- 调用 constexpr 构造函数(和默认构造函数)
- 使用 carrays 和
std::array
- 使用 static_asserts 和东西
typedef
和using
声明
C++14 添加:
- 您现在也可以使用 lambda
- 您可以在 constexpr 函数中修改变量
- 你可以有改变成员变量的constexpr成员函数
- 您可以将引用(非常量类型)传递给 constexpr 函数
C++20 添加内容:(C++20 将于 2020 年发布)
- 你现在可以分配内存了
- 你现在可以调用虚函数了
- 你可以有
try-catch
block
std::sort
是常量吗?
为了在 constexpr 上下文中使用一个函数,它必须被标记为 constexpr(它附带了一组关于你可以在函数中做什么的限制;这些在下面讨论)。在 C++11 中,std::sort
不是 constexpr,因为它打破了这些限制(直到 C++20 才成为 constexpr)。
但是,如果允许您使用 C++14,您可以编写自己的在编译时运行的排序函数。
关于c++ - 如何判断表达式是在编译时还是运行时求值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55918023/