7

考虑以下代码:

template<typename T>
constexpr inline T fma(T a, T b, T c)
{
    return a * b + c;
}

这编译得很好。但为什么会这样?理论上,constexpr 函数只能调用其他的 constexpr 函数。但是,不能保证运算符将是 constexpr 函数。例如,假设我有一些具有以下接口的类型:

 class someType
 {
    someType operator + (const someType &rhs);
    someType operator * (const someType &rhs);
 };

运算符 + 和 *不是constexpr。如果我编写以下代码:

fma(someType(), someType(), someType());

它应该无法编译,因为 constexpr 函数正在调用非 constexpr 函数。但它编译得很好。为什么是这样?

我正在使用带有 -std=c++0x 选项的 MinGW 的 G++ 编译器。

4

3 回答 3

5

如果您使用非常量表达式作为参数调用 constexpr 函数,则该函数将在运行时执行。

如果你这样做:

constexpr someType dummy = fma(someType(), someType(), someType());

它会失败,因为您强制将结果存储在一个constexpr类型中。这不能在编译时完成,因此会出现编译错误。

请注意,如果您同时提供了构造函数和in ,这起作用。constexprconstexpr operator+/*someType

于 2012-09-09T04:05:01.937 回答
5

从 C++11 标准的第 7.1.5.6 节:

If the instantiated template specialization of a constexpr function template or member function of a class
template would fail to satisfy the requirements for a constexpr function or constexpr constructor, that
specialization is not a constexpr function or constexpr constructor. [ Note: If the function is a member
function it will still be const as described below. — end note ] If no specialization of the template would
yield a constexpr function or constexpr constructor, the program is ill-formed; no diagnostic required.

这意味着如果 constexpr 函数模板使用模板参数实例化,则它会降级为非 constexpr 函数,这使其不是有效的 constexpr 函数。

如果无论你给它什么模板参数它都不是一个有效的 constexpr 函数,那么编译器可能会抱怨,但它不必抱怨。

于 2012-09-09T04:08:27.337 回答
0

由于模板通常在使用时检查错误,因此只有当您将其与具有非 constexpr 运算符的类型一起使用时,它才会出错。

于 2012-09-09T04:04:33.117 回答