簡體   English   中英

如何判斷表達式是在編譯時還是在運行時進行計算?

[英]How to tell if expression is evaluated at compile time or runtime?

我有一個相當大的Map對象,我希望有一個單獨的列表,其中的鍵已經排序。 這將在我的項目的許多其他源文件中使用。

問題是如何知道decalaration / definition何時是編譯時工作。 我應該在哪里找到是否是這種情況? 我的意思是怎么說?

在以下示例中,源文件中的列表是編譯時作業還是在運行時發生?

另外,有沒有一種方法可以在編譯時進行排序操作?

// 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補充:

  • 你現在也可以使用lambdas
  • 您可以修改constexpr函數內的變量
  • 你可以有constexpr成員函數來改變成員變量
  • 您可以將引用(非const類型)傳遞給constexpr函數

C ++ 20新增內容: (C ++ 20將於2020年推出)

  • 你現在可以分配內存
  • 您現在可以調用虛擬功能
  • 你可以有try-catch

std::sort constexpr?

為了在constexpr上下文中使用函數,必須將其標記為constexpr(它對函數中可以執行的操作提供了一組限制;這些將在下面討論)。 在C ++ 11中, std::sort不是constexpr,因為它打破了這些限制(在C ++ 20之前它不會是constexpr)。

但是,如果允許使用C ++ 14,則可以編寫自己的編譯時在編譯時運行的排序函數。

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

另外,有沒有一種方法可以在編譯時進行排序操作?

簡答:不。

答案很長。

不,因為std::sort()只是來自C ++ 20的constexpr (你標記了C ++ 11),因為在C ++ 11中, void函數( std::sort() )不能是constexpr ,因為QMapQList不是constexpr類(如果我沒有錯),因為你沒有聲明GMAP和其他對象作為constexpr等。

但是,假設有一個MyMap類中定義constexpr ,一個MyList類中聲明constexpr ,一個MySort()函數定義constexpr ,你可以寫類似的東西(從C ++ 14因為在C ++ 11你不能寫一個這樣開始復雜的constexpr功能)

constexpr MyList foo ()
{
  MyMap mm { /* some values */ };

  MyList ml { ml.keys() };

  MySort(ml.begin(), ml.end());

  return ml;
}

// ...

constexpr auto ml_final { foo() };

觀察到ml_final被聲明為constexpr

如果可能的話,這必須強制(pre C ++ 20)編譯器初始化值編譯時,或者如果不可能則給出編譯錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM