为什么constexpr使用模板?

Avi*_*Avi 7 c++ operator-overloading constant-expression constexpr

请考虑以下代码:

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

编译得很好.但为什么呢?理论上,constexpr函数只能调用其他constexpr函数.但是,不能保证运营商将是constexpr功能.例如,假设我有一些带有以下界面的类型:

 class someType
 {
    someType operator + (const someType &rhs);
    someType operator * (const someType &rhs);
 };
Run Code Online (Sandbox Code Playgroud)

运算符+和*不是 constexpr.如果我写下面的代码:

fma(someType(), someType(), someType());
Run Code Online (Sandbox Code Playgroud)

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

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

mfo*_*ini 5

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

如果你这样做:

constexpr someType dummy = fma(someType(), someType(), someType());
Run Code Online (Sandbox Code Playgroud)

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

请注意,如果您同时提供了构造函数和in ,那么这有效.constexprconstexpr operator+/*someType


Vau*_*ato 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.
Run Code Online (Sandbox Code Playgroud)

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

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