C++ 中的编译时函数是什么?
What is compile time function in C++?
我在这里(在 SO 上)搜索了这个问题,据我所知,所有问题都假设什么是编译时函数,但初学者几乎不可能知道那是什么意思,因为要知道的资源那是相当罕见的。
我找到了简短的 wikipedia article which shows how to write incomprehensible code by writing never-seen-before use of enums in C++, and a video,这是关于它的未来,但对此解释得很少。
在我看来,在C++中编写编译时函数有两种方式
constexpr
template<>
我已经对它们进行了简短的介绍,但我不知道它们是如何出现在这里的。
任何人都可以用一个足够好的例子来解释编译时函数,以便它包含它的大部分相关功能吗?
A "compile time function" 如您所见,所使用的术语不是 C++ 构造,它只是在编译时计算内容(因此,函数)的想法(与在 [=29= 时计算相反) ]time 或通过编译器外部的单独构建工具)。 C++ 以多种方式实现了这一点,您已经找到了其中两个:
模板确实可以用来计算任意东西,一组称为 "template metaprogramming" 的技术。这主要是偶然的,因为它们根本不是为此目的而设计的,因此疯狂的语法和与旧编译器的斗争。但在 C++03 及之前的版本中,这就是我们所拥有的。
constexpr
在看到编译时计算的需要后被添加到 C++11 中,并将它们带回到更理智的领域。从那以后,它的工具带一直在扩展,通过在正确的位置添加 constexpr
,允许越来越多看起来正常的代码在编译时成为 运行。
还可以提到宏元编程,Boost.Preprocessor就是一个很好的例子。但它比老式的模板元编程更古怪和神秘,所以如果你有选择的话你可能不想使用它。
如您所述,在 cpp 中,有两种在编译时评估代码的方法 - constexpr
函数和 template
元编程。
这些解决方案之间存在一些差异。 template
选项较旧,因此得到更广泛的编译器支持。另外 template
s 保证在编译时进行评估,而 constexpr
有点像内联 - 它只建议编译器可以在编译时进行工作。对于 templates
,参数通常通过模板参数列表传递,而 constexpr
函数将参数作为常规函数(它们实际上是)。 constexpr
函数更好,因为它们可以在运行时作为常规函数调用。
现在是相似之处 - 必须可以在编译时评估它们的参数。因此它们必须是文字或其他编译时函数的结果。
说了这么多让我们来看看编译时max
函数:
template<int a, int b>
struct max_template {
static constexpr int value = a > b ? a : b;
};
constexpr int max_fun(int a, int b) {
return a > b ? a : b;
}
int main() {
int x = 2;
int y = 3;
int foo = max_fun(3, 2); // can be evaluated at compile time
int bar = max_template<3, 2>::value; // is surely evaluated at compile time
// won't compile without compile-time arguments
// int bar2 = max_template<x, y>::value; // is surely evaluated at compile time
int foo = max_fun(x, y); // will be evaluated at runtime
return 0;
}
我在这里(在 SO 上)搜索了这个问题,据我所知,所有问题都假设什么是编译时函数,但初学者几乎不可能知道那是什么意思,因为要知道的资源那是相当罕见的。
我找到了简短的 wikipedia article which shows how to write incomprehensible code by writing never-seen-before use of enums in C++, and a video,这是关于它的未来,但对此解释得很少。
在我看来,在C++中编写编译时函数有两种方式
constexpr
template<>
我已经对它们进行了简短的介绍,但我不知道它们是如何出现在这里的。
任何人都可以用一个足够好的例子来解释编译时函数,以便它包含它的大部分相关功能吗?
A "compile time function" 如您所见,所使用的术语不是 C++ 构造,它只是在编译时计算内容(因此,函数)的想法(与在 [=29= 时计算相反) ]time 或通过编译器外部的单独构建工具)。 C++ 以多种方式实现了这一点,您已经找到了其中两个:
模板确实可以用来计算任意东西,一组称为 "template metaprogramming" 的技术。这主要是偶然的,因为它们根本不是为此目的而设计的,因此疯狂的语法和与旧编译器的斗争。但在 C++03 及之前的版本中,这就是我们所拥有的。
constexpr
在看到编译时计算的需要后被添加到 C++11 中,并将它们带回到更理智的领域。从那以后,它的工具带一直在扩展,通过在正确的位置添加constexpr
,允许越来越多看起来正常的代码在编译时成为 运行。
还可以提到宏元编程,Boost.Preprocessor就是一个很好的例子。但它比老式的模板元编程更古怪和神秘,所以如果你有选择的话你可能不想使用它。
如您所述,在 cpp 中,有两种在编译时评估代码的方法 - constexpr
函数和 template
元编程。
这些解决方案之间存在一些差异。 template
选项较旧,因此得到更广泛的编译器支持。另外 template
s 保证在编译时进行评估,而 constexpr
有点像内联 - 它只建议编译器可以在编译时进行工作。对于 templates
,参数通常通过模板参数列表传递,而 constexpr
函数将参数作为常规函数(它们实际上是)。 constexpr
函数更好,因为它们可以在运行时作为常规函数调用。
现在是相似之处 - 必须可以在编译时评估它们的参数。因此它们必须是文字或其他编译时函数的结果。
说了这么多让我们来看看编译时max
函数:
template<int a, int b>
struct max_template {
static constexpr int value = a > b ? a : b;
};
constexpr int max_fun(int a, int b) {
return a > b ? a : b;
}
int main() {
int x = 2;
int y = 3;
int foo = max_fun(3, 2); // can be evaluated at compile time
int bar = max_template<3, 2>::value; // is surely evaluated at compile time
// won't compile without compile-time arguments
// int bar2 = max_template<x, y>::value; // is surely evaluated at compile time
int foo = max_fun(x, y); // will be evaluated at runtime
return 0;
}