重载函数调用编译时常量

Overloading function calls for compile-time constants

本文关键字:常量 编译 函数调用 重载      更新时间:2023-10-16

我很想知道是否可以区分使用编译时常量提供的参数和不使用的参数的函数调用?

例如:

int a = 2;
foo( a )  // #1: Compute at run-time
foo( 3 )  // #2: Compute at compile-time

有没有办法提供区分这两种情况的重载?或者更一般地说,如何检测文本类型的使用情况?

我已经研究了 constexpr

,但函数参数不能是 constexpr。使用相同的调用语法会很好,但能够根据参数是否是文字类型生成不同的代码。

您无法区分编译时文字int和运行时变量int。如果需要执行此操作,可以提供只能在编译时工作的重载:

void foo(int ); // run-time
template <int I>
void foo(std::integral_constant<int, I> ); // compile-time
我认为

上面的答案不知何故错过了问题试图表达的观点。

有没有办法提供区分这两种情况的重载?或者更一般地说,如何检测文本类型的使用情况?

这就是"右值引用"的用途。 文本类型是右值。

使用相同的调用语法会很好,但能够根据参数是否是文字类型生成不同的代码。

你可以简单地重载你的 foo() 函数,如下所示:

void foo(int&& a);

因此,当您使用文字调用函数时,例如 foo(3),编译器知道您需要上述重载,因为 3 是一个右值。如果将该函数调用为 foo(a),编译器将选取您的原始版本foo(const int& a);因为int a=2;是一个左值。

这为您提供了相同的调用语法。

在一般情况下,你无法在编译时计算 foo(3)。 如果 foo(x) 被定义为在当前日期中添加 x 天 - 并且您下周二首次运行该程序,该怎么办? 如果它确实是一个常量,则使用符号常量。 如果它是一个简单的函数,你可以尝试一个定义(它将在编译时被替换为实现 - 但它仍然会在运行时被评估)

例如

#define MIN(x,y) ((x)<(y)?(x):(y))