首页 > 解决方案 > 如何判断表达式是在编译时还是运行时评估的?

问题描述

我有一个相当大的 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());
}

标签: c++qtc++11

解决方案


如果将结果分配给constexpr变量、在static_assertornoexcept语句中使用或用作模板参数,则在编译时计算表达式。这称为 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 and using 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


推荐阅读