2

使用编译时常量整数的浮点计算是在编译时还是在运行时执行的?例如,什么时候计算除法运算:

template <int A, int B>
inline float fraction()
{
    return static_cast<float>(A) / B;
}
4

5 回答 5

2

对于这么简单的事情,编译器可能会在编译时完成。事实上,即使没有模板,编译器也可能会在编译时执行此操作,只要在编译时知道所有值:即,如果我们有inline float fraction(int A, int B),如果我们调用 ,它可能会在编译时执行除法fraction(1,2)

如果你想强制编译器在编译时做一些事情,你将不得不使用一些模板元编程技巧,我不确定你是否可以让它与浮点运算一起工作。但这是该技术的一个基本示例:

// Something similarly simple that doesn't use floating-point ;)
template <int A, int B>
struct Product {
    enum { value = A * B };
};

// Later:
... Product<3, 4>::value ...
于 2010-12-11T14:29:57.743 回答
1

最好的办法是查看生成的代码 - 无法保证浮点运算将在编译时执行,但在更高的优化级别上它们可能会执行,特别是对于像这样简单的事情。

(一些编译器可能会避免这样做,因为对于某些体系结构,浮点行为是在运行时可配置的。在编译时执行的操作的结果可能与在运行时执行的相同操作的结果不同。)

于 2010-12-11T14:27:21.397 回答
1

您应该等待带有 C++0x constexpr关键字实现的 gcc 4.6。

于 2010-12-11T14:30:30.913 回答
1

我相信它是实现定义的,但大多数编译器会在编译时评估常量表达式。但是,即使您没有进行以下修改:

template <int A, int B>
inline float fraction()
{
    static const float f = static_cast<float>(A) / B;
    return f ;
}

如果在运行时求值,至少会确保表达式只求值一次。

于 2010-12-11T14:48:15.913 回答
1

C 或 C++ 标准都不要求在编译时评估任何条带的常量表达式,但它们确实允许这样做。过去 20 年发布的大多数编译器都会评估算术表达式,因此如果不引发函数调用或内联代码很重要,请尽可能保持简单。

如果这些表达式的范围仅限于单个文件,您总是可以利用预处理器并#define FRACTION(a,b) (float(a)/float(b))为方便起见。我不建议在标题中执行此操作,除非您有一个好的方案来防止污染#include它的任何文件。

于 2010-12-11T16:10:23.480 回答