为什么constexpr使用模板?

时间:2012-09-09 03:43:43

标签: c++ operator-overloading constexpr constant-expression

请考虑以下代码:

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函数。但它编译得很好。这是为什么?

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

3 个答案:

答案 0 :(得分:5)

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

如果你这样做:

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

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

请注意,如果您在constexpr中同时提供constexpr构造函数和operator+/* someType,则此

答案 1 :(得分: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函数。

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

答案 2 :(得分:0)

由于模板主要是在使用时检查错误,因此只有在使用非constexpr操作符的类型时,它才会出错。