条件 constexpr 函数

conditional constexpr functions

我这里有一个函数可能是 constexpr 的情况。通常,只有在上下文允许的情况下,才会添加 constexpr 并使用常量求值。然而,尽管没有在 constexpr 上下文中使用它,但以下代码投诉:

template <typename T>
struct Wrapper
{
    friend constexpr bool operator==(const Wrapper& crLhs, const Wrapper& crRhs) noexcept
    {
        return crLhs.m_t == crRhs.m_t;
    }

    T m_t = {};
};

使用 Visual Studio 2017 15.9.20 这会给出“错误 C3615:constexpr 函数 'operator ==' 无法生成常量表达式”,例如为 std::string 实例化。信息是正确的,但我没有在 constexpr 上下文中实例化它。

void f()
{
   bool b;

   Wrapper<int>  a;

   b = a == a; //ok

   Wrapper<std::string> c;

   b = c == c;  //C3615, but not using constexpr context
}

我可以通过使用成员模板或删除 constexpr 来应用解决方法,但是这里是否有花哨的技巧来两全其美(即适用时的 constexpr)?

你的代码没问题。这是旧版本 MSVC 中的错误。

此错误已在 MSVC 19.22 版本中修复,并且可以正常编译。在这里我们可以看到两个编译器版本的并排:https://godbolt.org/z/79kXFm

19.22 之后的所有版本(包括 19.22)都会编译它,但是 19.21 及以下版本会错误地给出错误 C3615,即使它们都设置为使用 C++11。

GCC 和 Clang 从来没有这个错误。

这个错误只出现在 MSVC 中,即使是非常旧版本的 GCC 和 Clang 也可以编译代码而不会出现错误。

你该怎么办?

如果可能,您应该直接使用较新版本的 Visual Studio。这是升级编译器的最简单选项,如果您移动到较新的版本,编译器应该会收到错误修复和升级。如果这不是一个选项,我会 google 不同的方式来升级编译器本身。这个might be helpful