我有一个很大的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());
}
答案 0 :(得分:6)
如果将结果分配给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,则可以编写自己的在编译时可以使用的排序函数。
答案 1 :(得分:1)
还可以在编译时进行排序操作吗?
简短回答:否。
长答案。
否,因为std::sort()
仅来自C ++ 20(您标记了C ++ 11),因为constexpr
函数(void
)不能为std::sort()
在C ++ 11中为constexpr
,因为QMap
和QList
不是constexpr
类(如果我没记错的话),因为您没有声明{{1 }}和其他涉及GMAP
的对象,等等。
但是,假设有一个constexpr
类定义了MyMap
,一个constexpr
类定义了MyList
,一个constexpr
函数定义了MySort()
,您可以编写类似的内容(从C ++ 14开始,因为在C ++ 11中无法编写如此复杂的constexpr
函数)
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
。
如果可能的话,这有必要强加(在C ++ 20之前)编译器初始化值编译时,或者在不可能的情况下给出编译错误。