当 constexpr 函数调用非 constexpr 函数时,未实例化模板中的编译器错误

Compiler error in uninstantiated template when a constexpr function calls a non-constexpr one

在下面的一段C++11代码中,函数getconstexpr 但它试图通过非 constexpr 构造函数构造一个实例。

template <typename T>
struct S
{
    S() {}
    static constexpr S get() { return S(); }
};

int main()
{
    // S<int> s1;
    // auto s2 = s1.get();
}

虽然这段代码可以用 GCC 编译,但它在我们使用的编译器上失败了 处理消息

constexpr function return is non-constant.

我们开始讨论是否允许编译器在 这个案例。我认为编译器必须接受代码。否则我会 看不到 std::time_point 在 C++11 中如何工作,因为它的构造函数是 constexpr 仅自 C++14 起。

那么这是执行质量问题还是标准说的 关于未实例化的模板 w.r.t constexpr? 此外,如果评论中的代码是,它会改变什么吗? 已激活(即在非 constexpr 上调用 constexpr 函数 对象)?

这一行没问题:

S<int> s1;

但是 get 的以下定义格式不正确:

static constexpr S get() { return S(); }

因为它没有 return 文字类型,因为 S 没有 constexpr 构造函数。

来自 C++11 标准草案部分 7.1.5 constexpr 说明符 [dcl.constexpr]:

The definition of a constexpr function shall satisfy the following constraints:

  • its return type shall be a literal type;

后面的部分说(强调我的):

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.

注意在非模板情况下,gcc 和 clang 都会产生错误,因为 return 类型不是文字 see it live.