![](/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.