c++ - 如何判断表达式是在编译时还是运行时求值?

标签 c++ qt c++11

我有一个相当大的 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_assertnoexcept 语句中使用,或使用作为模板参数。这称为 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 和东西
  • typedefusing 声明

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,您可以编写自己的在编译时运行的排序函数。

完整概述: https://en.cppreference.com/w/cpp/language/constexpr

关于c++ - 如何判断表达式是在编译时还是运行时求值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55918023/

相关文章:

c++ - 私有(private)静态变量建立不变量

c++ - 使用opengl创建交互式对话框

c++ - 编译时得到错误: 'QtGui/QAction' file not found #include <QtGui/QAction>

c++ - QPixmap 图像文件未出现在 QGraphicsScene 上

c++ - 为什么这个结构的大小不正确

c++ - 非 QObject 中的 Qt 容器

c++ - 赋值运算符的分支与值而不是引用

c++ - 如何使用 std::chrono::duration 作为模板参数?

c++ - 如何在一对 vector 中输入单个值?

c++ - 在 C++ 中的 operator= 之后调用的析构函数