![](/img/trans.png)
[英]How to tell if `constexpr` is evaluated at compile time (without manual inspection)
[英]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_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:
std::array
typedef
和using
聲明 C ++ 14補充:
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
,因為QMap
和QList
不是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.